java多线程学习-java.util.concurrent详解(六) Exchanger
转载于:http://janeky.iteye.com/blog/769965
我们先来学习一下JDK1.5 API中关于这个类的详细介绍:
“可以在pair中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。 “
应用举例:有两个缓存区,两个线程分别向两个缓存区fill和take,当且仅当一个满了,两个缓存区交换
代码如下
package com.winterbe.java8.samples.concurrent; import java.util.ArrayList; import java.util.concurrent.Exchanger; public class TestExchanger { public static void main(String[] args) { final Exchanger<ArrayList<Integer>> exchanger = new Exchanger<ArrayList<Integer>>(); final ArrayList<Integer> buff1 = new ArrayList<Integer>(10); final ArrayList<Integer> buff2 = new ArrayList<Integer>(10); final ArrayList<Integer> buff3 = new ArrayList<Integer>(10); new Thread(new Runnable() { @Override public void run() { ArrayList<Integer> buff = buff1; try { while (true) { if (buff.size() >= 10) { buff = exchanger.exchange(buff);//开始跟另外一个线程交互数据 System.out.println("exchange buff1"); buff.clear(); } buff.add((int)(Math.random()*100)); Thread.sleep((long)(Math.random()*1000)); } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); new Thread(new Runnable(){ @Override public void run() { ArrayList<Integer> buff=buff2; while(true){ try { for(Integer i:buff){ System.out.println("b2:"+i); } Thread.sleep(1000); buff=exchanger.exchange(buff);//开始跟另外一个线程交换数据 System.out.println("exchange buff2"); } catch (InterruptedException e) { e.printStackTrace(); } } }}).start(); new Thread(new Runnable(){ @Override public void run() { ArrayList<Integer> buff=buff3; while(true){ try { for(Integer i:buff){ System.out.println("b3:"+i); } Thread.sleep(1000); buff=exchanger.exchange(buff);//开始跟另外一个线程交换数据 System.out.println("exchange buff3"); } catch (InterruptedException e) { e.printStackTrace(); } } }}).start(); } }
总结:Exchanger在特定的使用场景比较有用(两个伙伴线程之间的数据交互)