Exchanger

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

构造函数:

创建一个新的 Exchanger。

public Exchanger()

方法:

public V exchange(V x) throws InterruptedException

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

示例:

package com.zero.test;

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangerTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ExecutorService service = Executors.newCachedThreadPool();
        final Exchanger exchanger = new Exchanger();
        service.execute(new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    String data1 = "...data1";
                    System.out.println("线程" + Thread.currentThread().getName()
                            + "正在把数据" + data1 + "换出去");
                    String data2 = (String) exchanger.exchange(data1);
                    System.out.println("线程" + Thread.currentThread().getName()
                            + "换回的数据为" + data2);
                } catch (Exception e) {

                }
            }
        });
        service.execute(new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    String data1 = "...data2";
                    System.out.println("线程" + Thread.currentThread().getName()
                            + "正在把数据" + data1 + "换出去");
                    String data2 = (String) exchanger.exchange(data1);
                    System.out.println("线程" + Thread.currentThread().getName()
                            + "换回的数据为" + data2);
                } catch (Exception e) {

                }
            }
        });
        service.shutdown();
    }
}

// 该类使用 Exchanger 在线程间交换缓冲区
// 在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程。
class FillAndEmpty {
    Exchanger<byte[]> exchanger = new Exchanger<byte[]>();
    byte[] initEmptyByte = new byte[255];
    byte[] initFullByte = new byte[255];
    volatile int length;

    class FillingLoop implements Runnable {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            byte[] currentByte = initEmptyByte;
            try {
                while (currentByte != null) {
                    currentByte[length] = ' ';
                    if (length == 255) {
                        currentByte = exchanger.exchange(currentByte);
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

    class EmptyingLoop implements Runnable {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            byte[] currentByte = initFullByte;
            try {
                while (currentByte != null) {
                    byte a = currentByte[length];
                    length--;// length--并不是原子,仍存在问题,只是表述下意思
                    if (length == 0) {
                        currentByte = exchanger.exchange(currentByte);
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

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

你可能感兴趣的:(Exchanger)