目录
Exchanger交换器
Exchanger概念
Exchanger示例
Exchanger和Semaphore区别
借花献佛
Exchanger
概念
上图业务场景描述:A有球,想要和B的鱼交互,整个交互过程描述如下:
A在准备素材,球,准备的比较快,然后就发出交换诉求,exchange(球),发现B还没带着鱼来,就阻塞在这里。B这时还在钓鱼,等B钓到鱼后,立马发出交换诉求,exchange(鱼),发现A阻塞在那里了,就把A唤醒,然后两人互换了东西,A拥有了鱼,B拥有了球。
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.
在以上的描述中,有几个要点:
Exchanger
Exchanger
示例
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*;
//球线程
class BallTask implements Runnable
{
private Exchanger e;
public BallTask(Exchanger e){
this.e = e;
}
public void run(){
try{
long sleepTime = (long)(Math.random() * 2500) ;
String tName = Thread.currentThread().getName();
System.out.println(tName+"正在买球,用时["+sleepTime+"]才买到球,赶紧去换鱼...");
Thread.sleep(sleepTime);
String str = e.exchange(tName+":的球");
System.out.println("【"+tName+":的球】换到了-->【"+str+"】");
}
catch(Exception e){
}
finally{
}
}
}
//鱼线程
class FishTask implements Runnable
{
private Exchanger e;
public FishTask(Exchanger e){
this.e = e;
}
public void run(){
try{
long sleepTime = (long)(Math.random() * 2500) ;
String tName = Thread.currentThread().getName();
System.out.println(tName+"正在钓鱼,用时["+sleepTime+"]才钓到鱼,赶紧去换球...");
Thread.sleep(sleepTime);
String str = e.exchange(tName+":的鱼");
System.out.println("【"+tName+":的鱼】换到了-->【"+str+"】");
}
catch(Exception e){
}
finally{
}
}
}
public class ExchangerTest
{
public static void main(String[] args)
{
Exchanger e = new Exchanger();
BallTask bTask = new BallTask(e); //任务:球线程
FishTask fTask = new FishTask(e); //任务:鱼线程
Thread bThread = new Thread(bTask,"Ball");
Thread fThread = new Thread(fTask,"Fish");
bThread.start();
fThread.start();
System.out.println("我是主线程,准备看看你们交易情况...\n\r");
try{
bThread.join();
fThread.join();
}catch(Exception ep){}
System.out.println("\n\r我是主线程,已看到你们的交易结果...");
}
}
程序运行结果如下:
我是主线程,准备看看你们交易情况...
Ball正在买球,用时[88]才买到球,赶紧去换鱼...
Fish正在钓鱼,用时[2215]才钓到鱼,赶紧去换球...
【Fish:的鱼】换到了-->【Ball:的球】
【Ball:的球】 换到了-->【Fish:的鱼】
我是主线程,已看到你们的交易结果...
Exchanger和Semaphore区别
Exchanger
借花献佛
摘自博客(http://brokendreams.iteye.com/blog/2253956)
其实就是”我”和”你”(可能有多个”我”,多个”你”)在一个叫Slot的地方做交易(一手交钱,一手交货),过程分以下步骤:
1。我先到一个叫做Slot的交易场所交易,发现你已经到了,那我就尝试喊你交易,如果你回应了我,决定和我交易那么进入第2步;如果别人抢先一步把你喊走了,那我就进入第5步。
2。我拿出钱交给你,你可能会接收我的钱,然后把货给我,交易结束;也可能嫌我掏钱太慢(超时)或者接个电话(中断),TM的不卖了,走了,那我只能再找别人买货了(从头开始)。
3。我到交易地点的时候,你不在,那我先尝试把这个交易点给占了(一屁股做凳子上…),如果我成功抢占了单间(交易点),那就坐这儿等着你拿货来交易,进入第4步;如果被别人抢座了,那我只能在找别的地方儿了,进入第5步。
4。你拿着货来了,喊我交易,然后完成交易;也可能我等了好长时间你都没来,我不等了,继续找别人交易去,走的时候我看了一眼,一共没多少人,弄了这么多单间(交易地点Slot),太TM浪费了,我喊来交易地点管理员:一共也没几个人,搞这么多单间儿干毛,给哥撤一个!。然后再找别人买货(从头开始);或者我老大给我打了个电话,不让我买货了(中断)。
5。我跑去喊管理员,尼玛,就一个坑交易个毛啊,然后管理在一个更加开阔的地方开辟了好多个单间,然后我就挨个来看每个单间是否有人。如果有人我就问他是否可以交易,如果回应了我,那我就进入第2步。如果我没有人,那我就占着这个单间等其他人来交易,进入第4步。
6。如果我尝试了几次都没有成功,我就会认为,是不是我TM选的这个单间风水不好?不行,得换个地儿继续(从头开始);如果我尝试了多次发现还没有成功,怒了,把管理员喊来:给哥再开一个单间(Slot),加一个凳子,这么多人就这么几个破凳子够谁用!