java.util.concurrent

接口
异常
java.lang.Object
  继承者 java.util.concurrent.Exchanger<V>
类型参数:
V - 可以交换的对象类型

public class Exchanger<V>
     
extends Object

可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。

用法示例:以下是重点介绍的一个类,该类使用 Exchanger 在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程。

class FillAndEmpty {
   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
   DataBuffer initialEmptyBuffer = ... a made-up type
   DataBuffer initialFullBuffer = ...

   class FillingLoop implements Runnable {
     public void run() {
       DataBuffer currentBuffer = initialEmptyBuffer;
       try {
         while (currentBuffer != null) {
           addToBuffer(currentBuffer);
           if (currentBuffer.isFull())
             currentBuffer = exchanger.exchange(currentBuffer);
         }
       } catch (InterruptedException ex) { ... handle ... }
     }
   }

   class EmptyingLoop implements Runnable {
     public void run() {
       DataBuffer currentBuffer = initialFullBuffer;
       try {
         while (currentBuffer != null) {
           takeFromBuffer(currentBuffer);
           if (currentBuffer.isEmpty())
             currentBuffer = exchanger.exchange(currentBuffer);
         }
       } catch (InterruptedException ex) { ... handle ...}
     }
   }

   void start() {
     new Thread(new FillingLoop()).start();
     new Thread(new EmptyingLoop()).start();
   }
  }
 

内存一致性效果:对于通过 Exchanger 成功交换对象的每对线程,每个线程中在 exchange() 之前的操作 happen-before 从另一线程中相应的 exchange() 返回的后续操作。

从以下版本开始:
1.5

构造方法摘要
Exchanger()
          创建一个新的 Exchanger。
 
方法摘要
 V exchange(V x)
          等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
 V exchange(V x, long timeout, TimeUnit unit)
          等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

构造方法详细信息

Exchanger

public Exchanger()
创建一个新的 Exchanger。

方法详细信息

exchange

public V exchange(V x)
           throws InterruptedException
等待另一个线程到达此交换点(除非当前线程被 中断),然后将给定的对象传送给该线程,并接收该线程的对象。

如果另一个线程已经在交换点等待,则出于线程调度目的,继续执行此线程,并接收当前线程传入的对象。当前线程立即返回,接收其他线程传递的交换对象。

如果还没有其他线程在交换点等待,则出于调度目的,禁用当前线程,且在发生以下两种情况之一前,该线程将一直处于休眠状态:

  • 其他某个线程进入交换点;或者
  • 其他某个线程中断当前线程。

如果当前线程:

  • 在进入此方法时已经设置了该线程的中断状态;或者
  • 在等待交换时被中断
则抛出 InterruptedException,并且清除当前线程的已中断状态。

参数:
x - 要交换的对象
返回:
另一个线程提供的对象
抛出:
InterruptedException - 如果当前线程在等待时被中断

exchange

public V exchange(V x,
                  long timeout,
                  TimeUnit unit)
           throws InterruptedException,
                  TimeoutException
等待另一个线程到达此交换点(除非当前线程被 中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。

如果另一个线程已经在交换点上等待,则出于线程调度目的,继续执行此线程,并接收当前线程传入的对象。当前线程立即返回,并接收其他线程传递的交换对象。

如果还没有其他线程在交换点等待,则出于调度目的,禁用当前线程,且在发生以下三种情况之一前,该线程将一直处于休眠状态:

  • 其他某个线程进入交换点;或者
  • 其他某个线程中断当前线程;或者
  • 已超出指定的等待时间。

如果当前线程:

  • 在进入此方法时已经设置其中断状态;或者
  • 在等待交换时被中断
则抛出 InterruptedException,并且清除当前线程的已中断状态。

如果超出指定的等待时间,则抛出 TimeoutException 异常。如果该时间小于等于零,则此方法根本不会等待。

参数:
x - 要交换的对象
timeout - 要等待的最长时间
unit - timeout 参数的时间单位
返回:
其他线程提供的对象
抛出:
InterruptedException - 如果当前线程在等待时被中断
TimeoutException - 如果在另一个线程进入交换点之前已经到达指定的等待时间