一、定义
Exchanger是一个用于线程间数据交换的工具类,它提供一个公共点,在这个公共点,两个线程可以交换彼此的数据。
当一个线程调用exchange方法后将进入等待状态,直到另外一个线程调用exchange方法,双方完成数据交换后继续执行。
Exchanger 是 JDK 1.5 开始提供的一个用于两个工作线程之间交换数据的封装工具类,简单说就是一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据。
从定义来看Exchanger是用于线程间进行通信、数据交换。Exchanger提供了一个同步点exchange方法,两个线程调用exchange方法时,无论调用时间先后,两个线程会互相等到线程到达exchange方法调用点,此时两个线程可以交换数据,将本线程产出数据传递给对方。
/*** Waits for another thread to arrive at this exchange point (unless* the current thread is {@linkplain Thread#interrupt interrupted}),* and then transfers the given object to it, receiving its object* in return.** <p>If another thread is already waiting at the exchange point then* it is resumed for thread scheduling purposes and receives the object* passed in by the current thread. The current thread returns immediately,* receiving the object passed to the exchange by that other thread.** <p>If no other thread is already waiting at the exchange then the* current thread is disabled for thread scheduling purposes and lies* dormant until one of two things happens:* <ul>* <li>Some other thread enters the exchange; or* <li>Some other thread {@linkplain Thread#interrupt interrupts}* the current thread.* </ul>* <p>If the current thread:* <ul>* <li>has its interrupted status set on entry to this method; or* <li>is {@linkplain Thread#interrupt interrupted} while waiting* for the exchange,* </ul>* then {@link InterruptedException} is thrown and the current thread's* interrupted status is cleared.** @param x the object to exchange* @return the object provided by the other thread* @throws InterruptedException if the current thread was* interrupted while waiting*/@SuppressWarnings("unchecked")public V exchange(V x) throws InterruptedException {Object v;Object item = (x == null) ? NULL_ITEM : x; // translate null argsif ((arena != null ||(v = slotExchange(item, false, 0L)) == null) &&((Thread.interrupted() || // disambiguates null return(v = arenaExchange(item, false, 0L)) == null)))throw new InterruptedException();return (v == NULL_ITEM) ? null : (V)v;}
/*** Waits for another thread to arrive at this exchange point (unless* the current thread is {@linkplain Thread#interrupt interrupted} or* the specified waiting time elapses), and then transfers the given* object to it, receiving its object in return.** <p>If another thread is already waiting at the exchange point then* it is resumed for thread scheduling purposes and receives the object* passed in by the current thread. The current thread returns immediately,* receiving the object passed to the exchange by that other thread.** <p>If no other thread is already waiting at the exchange then the* current thread is disabled for thread scheduling purposes and lies* dormant until one of three things happens:* <ul>* <li>Some other thread enters the exchange; or* <li>Some other thread {@linkplain Thread#interrupt interrupts}* the current thread; or* <li>The specified waiting time elapses.* </ul>* <p>If the current thread:* <ul>* <li>has its interrupted status set on entry to this method; or* <li>is {@linkplain Thread#interrupt interrupted} while waiting* for the exchange,* </ul>* then {@link InterruptedException} is thrown and the current thread's* interrupted status is cleared.** <p>If the specified waiting time elapses then {@link* TimeoutException} is thrown. If the time is less than or equal* to zero, the method will not wait at all.** @param x the object to exchange* @param timeout the maximum time to wait* @param unit the time unit of the {@code timeout} argument* @return the object provided by the other thread* @throws InterruptedException if the current thread was* interrupted while waiting* @throws TimeoutException if the specified waiting time elapses* before another thread enters the exchange*/@SuppressWarnings("unchecked")public V exchange(V x, long timeout, TimeUnit unit)throws InterruptedException, TimeoutException {Object v;Object item = (x == null) ? NULL_ITEM : x;long ns = unit.toNanos(timeout);if ((arena != null ||(v = slotExchange(item, true, ns)) == null) &&((Thread.interrupted() ||(v = arenaExchange(item, true, ns)) == null)))throw new InterruptedException();if (v == TIMED_OUT)throw new TimeoutException();return (v == NULL_ITEM) ? null : (V)v;}
V exchange(V v):等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
V exchange(V v, long timeout, TimeUnit unit):等待另一个线程到达此交换点,或者当前线程被中断——抛出中断异常;又或者是等候超时——抛出超时异常,然后将给定的对象传送给该线程,并接收该线程的对象。