Java中的交换器Exchanger

时间:2020-01-09 10:35:10  来源:igfitidea点击:

作为Java 5中java.util.concurrent包的一部分,添加了许多同步辅助,例如CyclicBarrier,Semaphore。作为Java并发性的一部分添加的另一个同步辅助工具是Exchanger。在本文中,我们将介绍Java中的Exchanger,它如何工作以及Exchanger的示例。

Java并发中的Exchanger

Java中的Exchanger是一种同步辅助工具,有助于在两个线程之间交换数据。当两个线程调用exchange()方法时,将交换这两个线程提供的对象。

Exchanger可用于生产者-消费者方案中,其中生产者线程产生一个缓冲区,该缓冲区可与使用者线程中的空缓冲区交换。

Java Exchanger类构造函数

Exchanger类只有一个构造函数。

  • Exchanger()–创建一个新的Exchanger。

Exchanger类中的方法

Java中的Exchanger类只有一个方法exchange(),该方法具有两种重载形式。

  • exchange(V x)–等待另一个线程到达此交换点(除非当前线程被中断),然后将给定对象传输到该对象,并返回其对象。
  • exchange(V x,long timeout,TimeUnit unit)–等待另一个线程到达此交换点(除非当前线程被中断或者经过了指定的等待时间),然后将给定对象传送给它,并在其中接收其对象返回。

Java Exchanger示例

这是生产者使用者线程的示例,其中线程使用Exchanger交换数据。交换的数据为DataBuffer类型。

数据缓冲区

import java.util.ArrayList;
import java.util.List;

public class DataBuffer {
  private List data = new ArrayList<>();

  public String getData() {
    return data.remove(0);
  }
  public void addToBuffer(String str) {
    data.add(str);
  }
  public boolean isFull() {
    if(data.size() == 1) 
      return true;
    return false;
  }
}
public class ExchangerDemo {
  public static void main(String[] args) {
    Exchanger ex = new Exchanger();
    // Starting two threads
    new Thread(new Producer(ex)).start();
    new Thread(new Consumer(ex)).start();
  }
}
// Producer class
class Producer implements Runnable {
  Exchanger ex;
  DataBuffer producerBuffer;
  Producer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer producerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){
      producerBuffer.addToBuffer("Producer" + i);
      try {
        if (producerBuffer.isFull()) {
          // exchange
          producerBuffer = ex.exchange(producerBuffer);
        }
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}
// Consumer class
class Consumer implements Runnable {
  Exchanger ex;
  DataBuffer consumerBuffer;
  Consumer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer consumerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){        	
      try {  
        System.out.println("waiting...");
        consumerBuffer = ex.exchange(consumerBuffer);
        System.out.println("Received- " + consumerBuffer.getData());
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}

输出:

waiting...
Received- Producer0
waiting...
Received- Producer1
waiting...
Received- Producer2