Exchanger

    java.util.concurrent包下Exchanger类可以实现两个线程之间的数据交换,其中参数T是泛型,表示交换的对象类型。

 

    Exchanger只有一个无参构造器,Exchanger()

 

    有两个重载方法exchange(V x)exchange(V x, long timeout, Timeunit, unit)。作用是等待另一个线程达到此交换点(除非当前线程被中断),然后将给定对象传送给该线程,并接收该线程持有的对象;如果另一个线程已经在交换点等待,则出于线程调度目的,继续执行此线程,并接收当前线程传入的对象,当前线程立即返回,接收其他线程传递的交换对象。exchange(V x, long timeout, Timeunit, unit)可以设置等待时间,如果超出等待时间则抛出TimeoutException异常。

 

    下面我们举个例子来体会Exchanger的用法

    数千年前的远古时代,在还没有“钱”的概念的时候,老祖宗们进行商品交换的方式是“以物易物”,虽然物物价值并不一定相等,但是这在当时也不失为一种好的方法。下面我们就通过Exchanger来实现“物物交换”


package com.gk.thread.exchanger;

import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExchangerDemo {
	
	public static void main(String[] args) {
		
			Exchanger exch = new Exchanger();			
			
			
			new Thread() {
				
				@Override
				public void run() {
					
					this.setName("zhangSan");
					if (! this.isInterrupted()) {
						Animal animal = new Animal("牛", 1);
						System.out.println(this.getName() + "交换前拥有 : " + animal);
						
						try {
							
							animal = exch.exchange(animal, 3L, TimeUnit.SECONDS);	// 进行交换,等待时间为3秒
							
						} catch (InterruptedException e) {
							throw new RuntimeException(e);
						} catch (TimeoutException e) {
							System.out.println("等待超时...");
							System.exit(0);		// 如果不强制退出的话,对方线程就会无限等待下去
							
						}
						
						System.out.println(this.getName() + "交换后拥有 : " + animal);
							
					}
					
				}
				
			}.start();
			
			/////////////////////////////////////
			
			new Thread() {
				
				@Override
				public void run() {
					
					this.setName("liSi");
					if (! this.isInterrupted()) {
						Animal animal = new Animal("羊", 2);
						System.out.println(this.getName() + "交换前拥有 : " + animal);
						
						try {
							
							Thread.sleep(1000 * 2);		// 通过设置休眠时间来改变超时的状态
							
							animal = exch.exchange(animal);		// 进行交换
							
						} catch (InterruptedException e) {
							throw new RuntimeException(e);
						}
						
						System.out.println(this.getName() + "交换后拥有 : " + animal);
							
					}
					
				}
				
			}.start();

	}

}

package com.gk.thread.exchanger;

public class Animal {
	
	private String name;
	private int number;


	public Animal(String name, int number) {
		this.name = name;
		this.number = number;
	}

	@Override
	public String toString() {
		
		return name + ", " + number + "只...";
	}
	
}

Exchanger_第1张图片

    从运行结果可以看出,在交换之前,zhangSan拥有的是1只牛,liSi拥有的是2只羊,交换之后,zhangSan拥有的是2只羊,liSi拥有的是1只牛。从而简单实现了两个线程之间的数据交换。

       有兴趣的话,也可以基于上面代码,测试中断和超时时程序运行的效果。


你可能感兴趣的:(java并发)