从JDK1.5版本开始开始提供线程间数据交换的功能,该功能可以通过Exchanger类完成。
Exchanger 类 定义:
public class Exchanger<V> extends Object
参数V 表示要交换的数据类型。
该类从Object类继承,它提供了一个同步点,在该同步点上线程可以交换数据,一个线程通过exchange() 方法将其数据提给另一个线程,并接收另一个线程的数据。
方法 exchange()定义的形式如下:
V exchange(V x)
该方法将等待另一个线程到达交换点,然后交换指定的数据x,该方法将返回交换后的数据。
demo 示例:
使用Exchanger 模拟实现生产者消费者问题。
问题分析:
设定两个缓冲区,包括空缓冲区和满缓冲区,空缓冲区分配给生产者,用于向其中存放数据,满缓冲区分配给消费者,用于从其中取出数据消费。当生产者将空缓冲区装满,并且消费者将满缓冲区取空后,生产者和消费者的缓冲区交换,
然后生产者继续存放数据,消费者继续取出数据,这样循环往复进行。
//缓冲区类
public class DataBuffer{
//定义一个链表 作为缓冲区
LinkedList<Integer> buffer;
DataBuffer(){
buffer = new LinkedList<Integer>();
}
//生产数据
public void full(){
while(!isFull()){
add();
}
}
//消费数据
public void empty(){
while(!isEmpty()){
take();
}
}
//是否满
public boolean isFull(){
if(buffer.size()>=100){
return true;
}else{
return false;
}
}
//是否空
public boolean isEmpty(){
return buffer.isEmpty();
}
//放入数据
public void add(){
buffer.addLast((int)(Math.random()*100));
}
//取出数据
public void take(){
buffer.removeFirst();
}
}
//定义线程类EmptyingBuffer,用于清空缓冲区
public class EmptyingBuffer extends Thread{
Exchanger<DataBuffer> exchanger;
DataBuffer buffer;
ThreadLocal<String> threadName = new ThreadLocal<String>(){
protected String initialValue() {
return getName()+"------"+"消费线程"+"》》》》》》";
}
};
public EmptyingBuffer(DataBuffer buffer,Exchanger<DataBuffer> exchanger){
this.exchanger = exchanger;
this.buffer = buffer;
}
public void run(){
try{
while(!buffer.isEmpty()){
if(buffer.isFull()){
System.out.println(threadName.get()+"的缓冲区已满,开始消费!");
}
buffer.take();
if(buffer.isEmpty()){
System.out.println(threadName.get()+"的缓冲区已清空,等待交互数据!");
buffer = exchanger.exchange(buffer);
System.out.println(threadName.get()+"数据交换完成!");
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//定义线程类FullingBuffer,用于放入数据
public class FillingBuffer extends Thread{
DataBuffer buffer;
Exchanger<DataBuffer> exchanger;
ThreadLocal<String> threadName = new ThreadLocal<String>(){
protected String initialValue() {
return getName()+"------"+"生产线程"+"》》》》》》";
}
};
public FillingBuffer(DataBuffer buffer,Exchanger<DataBuffer> exchanger){
this.buffer = buffer;
this.exchanger = exchanger;
}
public void run(){
try{
while(!buffer.isFull()){
if(buffer.isEmpty()){
System.out.println(threadName.get()+"的缓冲已空,开始放入!");
}
buffer.add();
if(buffer.isFull()){
System.out.println(threadName.get()+"的缓冲区已满,等待交换数据!");
buffer = exchanger.exchange(buffer);
System.out.println(threadName.get()+"数据交换完成!");
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//测试启动类
public class Index{
public static void main(String [] args){
DataBuffer fbuffer = new DataBuffer();
fbuffer.full();
DataBuffer ebuffer = new DataBuffer();
ebuffer.empty();
Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
Thread fillingBuffer = new FullingBuffer(ebuffer,exchanger);
Thread emptyingBuffer = new EmptyingBuffer(fbuffer,exchanger);
fillingBuffer.start();
emptyingBuffer.start();
}
}
运行结果:
Thread-0------生产线程》》》》》》的缓冲已空,开始放入!
Thread-0------生产线程》》》》》》的缓冲区已满,等待交换数据!
Thread-0------生产线程》》》》》》数据交换完成!
Thread-0------生产线程》》》》》》的缓冲已空,开始放入!
Thread-1------消费线程》》》》》》数据交换完成!
Thread-1------消费线程》》》》》》的缓冲区已满,开始消费!
Thread-0------生产线程》》》》》》的缓冲区已满,等待交换数据!
Thread-1------消费线程》》》》》》的缓冲区已清空,等待交互数据!
Thread-1------消费线程》》》》》》数据交换完成!
Thread-1------消费线程》》》》》》的缓冲区已满,开始消费!
Thread-1------消费线程》》》》》》的缓冲区已清空,等待交互数据!
Thread-0------生产线程》》》》》》数据交换完成!
Thread-0------生产线程》》》》》》的缓冲已空,开始放入!
Thread-0------生产线程》》》》》》的缓冲区已满,等待交换数据!
Thread-0------生产线程》》》》》》数据交换完成!
Thread-0------生产线程》》》》》》的缓冲已空,开始放入!
Thread-0------生产线程》》》》》》的缓冲区已满,等待交换数据!
Thread-1------消费线程》》》》》》数据交换完成!
Thread-1------消费线程》》》》》》的缓冲区已满,开始消费!
Thread-1------消费线程》》》》》》的缓冲区已清空,等待交互数据!
Thread-1------消费线程》》》》》》数据交换完成!
Thread-1------消费线程》》》》》》的缓冲区已满,开始消费!
Thread-1------消费线程》》》》》》的缓冲区已清空,等待交互数据!