1. 程式人生 > >Java併發——交換器

Java併發——交換器

1. 交換器

交換器提供了一個執行緒彼此之間能夠交換物件的同步點。

泛型類java.util.concurrent.Exchanger<V>實現了交換器。

Exchanger<V>類中的主要方法就是:exchange(V x)方法,成對的兩個執行緒之間,都呼叫了該方法,就能在兩個執行緒彼此都準備好資料後,成功的交換資料給對方,然後各自返回。如果想支援成對的兩個執行緒之間,一個沒耐性,等的時間過長,或者被打斷了就不交換資料了,可以使用exchange(V x, long timeout, TimeUnit unit)方法。

2.常用方法

(1)Exchanger()建構函式

初始化一個交換器

(2)V exchange(V x)

在這個互動點上等待其他執行緒到達(除非呼叫執行緒被中斷了),之後將所給物件傳入其中,接收其他執行緒的物件作為返回。

(3)V exchange(V x, long timeout, TimeUnit unit)

指定呼叫執行緒願意等待的時長,剩下的和上一個方法相同。

3. 示例

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangeTest {

	public static void main(String[] args)
	{
		final Exchanger<String> exchanger = new Exchanger<String>();
		Runnable rcat = new Runnable() {
			@Override
			public void run()
			{
				try {
					String data1 = "小魚乾";
					String name = Thread.currentThread().getName();
					System.out.println(name + "正在把食物" + data1 + "交換出去。" );
					Thread.sleep((long)(Math.random()*1000));
					String data2 = (String)exchanger.exchange(data1);
					System.out.println(name + "交換回來的食物為:" + data2);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		};
		
		Runnable rdog = new Runnable() {
			@Override
			public void run()
			{
				try {
					String data1 = "小骨頭";
					String name = Thread.currentThread().getName();
					System.out.println(name + "正在把食物" + data1 + "交換出去。" );
					Thread.sleep((long)(Math.random()*1000));
					String data2 = (String)exchanger.exchange(data1);
					System.out.println(name + "交換回來的食物為:" + data2);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		};
		
	    ExecutorService executorService = Executors.newCachedThreadPool();
	    executorService.submit(rcat);
	    executorService.submit(rdog);
	    try {
			Thread.sleep(2000);                   //模擬交換的過程
			System.out.println("交換完成!");
			executorService.shutdown();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 執行結果:

pool-1-thread-1正在把食物小魚乾交換出去。
pool-1-thread-2正在把食物小骨頭交換出去。
pool-1-thread-2交換回來的食物為:小魚乾
pool-1-thread-1交換回來的食物為:小骨頭
交換完成!