Java并发库(十七):线程交换Exchanger

深切怀念传智播客张孝祥老师,特将其代表作——Java并发库视频研读两遍,受益颇丰,记以后阅

17.java5Exchanger同步工具

       用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人会一直等待第二个人,直到第二个人拿着数据到来时,才能彼此交换数据。

举例:毒品交易  双方并不是同时到达,有先有后,只有都到达了,瞬间交换数据,各自飞

代码演示:

ExecutorService service =Executors.newCachedThreadPool();

final Exchanger exchanger = newExchanger();

       毒贩:

service.execute(new Runnable()

{     毒贩做的事

       public void run()

       {

       String(毒品) data1 = 毒品

       SOP(毒贩正在将data1换出去)

       Thread.sleep(Random)换的过程

       毒贩到位了,拿着毒品等待毒人接头,接头后就能换到钱了

       String data2 = (String)exchanger.exchange(data1);

       SOP(毒贩换到了钱:data2)

}

});

       毒人:

service.execute(new Runnable()

{     吸毒人做的事

       public void run()

       {

       String(钱) data1 = 钱

       SOP(毒人正在将data1换出去)

       Thread.sleep(Random)换的过程

       吸毒人到位了,拿着钱等待毒贩接头,接头后就能换到毒品了

       String data2 =(String)exchanger.exchange(data1);

       SOP(毒人换到了毒品:data2)

}

});

java.util.concurrent.Exchanger<V> V -可以交换的对象类型

可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给exchange方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。

用法示例:以下是重点介绍的一个类,该类使用Exchanger 在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程。

class FillAndEmpty {

  Exchanger<DataBuffer> exchanger = newExchanger<DataBuffer>();

  DataBuffer initialEmptyBuffer = ... a made-up type

  DataBuffer initialFullBuffer = ...

  class FillingLoop implements Runnable {

    public void run() {

      DataBuffer currentBuffer = initialEmptyBuffer;

      try {

        while (currentBuffer != null) {

           addToBuffer(currentBuffer);

          if (currentBuffer.isFull())

            currentBuffer = exchanger.exchange(currentBuffer);

        }

      } catch (InterruptedException ex) { ... handle ... }

    }

   }

  class EmptyingLoop implements Runnable {

    public void run() {

      DataBuffer currentBuffer = initialFullBuffer;

      try {

        while (currentBuffer != null) {

          takeFromBuffer(currentBuffer);

          if (currentBuffer.isEmpty())

            currentBuffer = exchanger.exchange(currentBuffer);

        }

      } catch (InterruptedException ex) { ... handle ...}

    }

   }

  void start() {

    new Thread(new FillingLoop()).start();

    new Thread(new EmptyingLoop()).start();

   }

  }

构造方法摘要

Exchanger()           创建一个新的 Exchanger。

方法摘要

 V

exchange(V x)           等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。

 V

exchange(V x, long timeout,TimeUnit unit)           等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。

 


public class ExchangerTest {

 

       publicstatic void main(String[] args) {

              ExecutorServiceservice = Executors.newCachedThreadPool();

              finalExchanger exchanger = new Exchanger();

              service.execute(newRunnable(){

                     publicvoid run() {

                            try{                           

 

                                   Stringdata1 = "zxx";

                                   System.out.println("线程" +Thread.currentThread().getName() +

                                   "正在把数据" + data1 +"换出去");

                                   Thread.sleep((long)(Math.random()*10000));

                                   Stringdata2 = (String)exchanger.exchange(data1);

                                   System.out.println("线程" + Thread.currentThread().getName()+

                                   "换回的数据为" + data2);

                            }catch(Exceptione){

                                  

                            }

                     }    

              });

              service.execute(newRunnable(){

                     publicvoid run() {

                            try{                           

 

                                   Stringdata1 = "lhm";

                                   System.out.println("线程" +Thread.currentThread().getName() +

                                   "正在把数据" + data1 +"换出去");

                                   Thread.sleep((long)(Math.random()*10000));                                 

                                   Stringdata2 = (String)exchanger.exchange(data1);

                                   System.out.println("线程" +Thread.currentThread().getName() +

                                   "换回的数据为" + data2);

                            }catch(Exceptione){

                                  

                            }                         

                     }    

              });         

       }

}



public class ExchangerTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final Exchanger exchanger = new Exchanger();
		service.execute(new Runnable(){
			public void run() {
				try {				

					String data1 = "zxx";
					System.out.println("线程" + Thread.currentThread().getName() + 
					"正在把数据" + data1 +"换出去");
					Thread.sleep((long)(Math.random()*10000));
					String data2 = (String)exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName() + 
					"换回的数据为" + data2);
				}catch(Exception e){
					
				}
			}	
		});
		service.execute(new Runnable(){
			public void run() {
				try {				

					String data1 = "lhm";
					System.out.println("线程" + Thread.currentThread().getName() + 
					"正在把数据" + data1 +"换出去");
					Thread.sleep((long)(Math.random()*10000));					
					String data2 = (String)exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName() + 
					"换回的数据为" + data2);
				}catch(Exception e){
					
				}				
			}	
		});		
	}
}


你可能感兴趣的:(Java并发库(十七):线程交换Exchanger)