1. 程式人生 > >Java多執行緒十一 Exchanger

Java多執行緒十一 Exchanger

Exchanger類介紹

A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, and receives its partner’s object on return. An Exchanger may be viewed as a bidirectional form of a SynchronousQueue. Exchangers may be useful in applications such as genetic algorithms and pipeline designs.

從javaDoc中我們可以總結如下幾點:
1. Exchanger是一個同步類
2. 在而且只能在兩個執行緒之間進行資料交換
3. 當一個執行緒到達exchange()呼叫點時,阻塞等待另外一個執行緒到達等待點,然後交換資料繼續各自的執行
4. 可以看做是一個雙向的同步佇列
5. 應用於基因演算法和流水線設計

示例一:

public class Consumer implements Runnable {
    List<Integer> list = new ArrayList<Integer>();
    Exchanger<List<Integer>> exchanger;

    public
Consumer(Exchanger<List<Integer>> exchanger) { super(); this.exchanger = exchanger; } public void run() { try { while (!Thread.interrupted()) { System.out.println("Consumer before exchager:" + this); list = exchanger.exchange(list); System.out.println("Consumer after exchager:"
+ this); } } catch (InterruptedException e) { e.printStackTrace(); } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("["); for (Integer value : list) { int i = 0; sb.append(" " + (++i) + value + " "); } sb.append("]"); return sb.toString(); } }
public class Producer implements Runnable {
    List<Integer> list = new ArrayList<Integer>();
    Exchanger<List<Integer>> exchanger = null;

    public Producer(Exchanger<List<Integer>> exchanger) {
        this.exchanger = exchanger;
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("Producer before exchanger" + this);
                Random rand = new Random();
                for (int i = 0; i < 10; i++) {
                    list.clear();
                    list.add(rand.nextInt(10000));
                    list.add(rand.nextInt(10000));
                    list.add(rand.nextInt(10000));
                    list.add(rand.nextInt(10000));
                    list.add(rand.nextInt(10000));
                    list.add(rand.nextInt(10000));
                }
                list = exchanger.exchange(list);
                System.out.println("Producer after exchanger" + this);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (Integer value : list) {
            int i = 0;
            sb.append(" " + (++i) + value + " ");
        }
        sb.append("]");
        return sb.toString();
    }

}
public class ExchangerDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
        ExecutorService service = Executors.newFixedThreadPool(2);
        service.execute(new Consumer(exchanger));
        service.execute(new Producer(exchanger));
        TimeUnit.SECONDS.sleep(1);
        service.shutdownNow();
    }
}

輸出結果如下:

Consumer after exchager:[ 1275  15315  17950  18047  13475  15804 ]
Consumer before exchager:[ 1275  15315  17950  18047  13475  15804 ]
Producer before exchanger[ 13511  12842  19060  13990  15241  18850 ]
Producer after exchanger[ 1275  15315  17950  18047  13475  15804 ]
Producer before exchanger[ 1275  15315  17950  18047  13475  15804 ]
Consumer after exchager:[ 13466  17312  1759  16423  16511  15417 ]
...