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在特定的使用场景比较有用(两个伙伴线程之间的数据交互) 

posted @ 2015-10-27 16:23  Tom Fan  阅读(379)  评论(0编辑  收藏  举报