java并发库 Exchanger 简析

来源:互联网 发布:录音软件cool edit 编辑:程序博客网 时间:2024/06/07 09:57

import java.util.concurrent.Exchanger;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

 

public class ExchangerTest {

public static void main(String[] args) {

ExecutorService service = Executors.newCachedThreadPool();

final Exchanger<String> change = new Exchanger();

exchangeData(service, change,"a");

exchangeData(service, change,"b");

exchangeData(service, change,"c");

exchangeData(service, change,"d");

service.shutdown();

}

private static void exchangeData(ExecutorService service,

final Exchanger<String> change,final String data) {

service.execute(new Runnable(){

@Override

public void run() {

try{

System.out.println(Thread.currentThread().getName() + " is exchanging data: " + data);

Thread.sleep(1000);

String data2 = (String) change.exchange(data, 1000, TimeUnit.MILLISECONDS);

System.out.println(Thread.currentThread().getName() + " get data: " + data2);

}catch(Exception e){

e.printStackTrace();

}

}

});

}

}

运行结果:

pool-1-thread-1 is exchanging data: a

pool-1-thread-3 is exchanging data: c

pool-1-thread-2 is exchanging data: b

pool-1-thread-4 is exchanging data: d

pool-1-thread-5 is exchanging data: e

pool-1-thread-6 is exchanging data: f

pool-1-thread-4 get data: c

pool-1-thread-2 get data: f

pool-1-thread-3 get data: d

pool-1-thread-1 get data: e

pool-1-thread-6 get data: b

pool-1-thread-5 get data: a

 

Exchanger必须是偶数个线程间的交换,否则会有一个线程一直拿不到数据,从而抛出java.util.concurrent.TimeoutException异常

多数情况下,一个线程启动后,只要发现有线程已经交出数据,就按照FCFS原则成为它的交换对象。

但由于线程调度的不确定性,也会出现与后来的线程交换数据的情形。

由此联想到一个形象的比喻,Exchanger就好比一场相亲大会,过来相亲的人一般都是剩斗士,甚至斗战剩佛。往往,一旦遇上一个异性,马上就可以谈妥…… 但也有人坚持宁缺毋滥,非要等到一个合适的人来!