1. 程式人生 > >java.util.concurrent包(7)-Exchanger使用

java.util.concurrent包(7)-Exchanger使用

Java 併發 API 提供了一種允許2個併發任務間相互交換資料的同步應用。更具體的說,Exchanger類允許在2個執行緒間定義同步點,當2個執行緒到達這個點,他們相互交換資料型別,使用第一個執行緒的資料型別變成第二個的,然後第二個執行緒的資料型別變成第一個的。示例1
一個人有零食,另一個人有錢,他們兩個想等價交換,對好口號在某個地方相見,一個人先到了之後,必須等另一個人帶著需要的東西來了之後,才能開始交換。
public class ExchangerTest
{
	public static void main(String[] args)
	{
		ExecutorService service = Executors.newCachedThreadPool();
		final Exchanger<String> exchanger = new Exchanger<String>();
		service.execute(new Runnable()
		{
			public void run()
			{
				try
				{
					String data1 = "零食";
					System.out.println("執行緒" + Thread.currentThread().getName() + "正在把資料" + data1 + "換出去");
					Thread.sleep((long) (Math.random() * 1000));
					String data2 = exchanger.exchange(data1);
					System.out.println("執行緒" + Thread.currentThread().getName() + "換回的資料為" + data2);
				}
				catch (Exception e)
				{
				}
			}
		});

		service.execute(new Runnable()
		{
			public void run()
			{
				try
				{
					String data1 = "錢";
					System.out.println("執行緒" + Thread.currentThread().getName() + "正在把資料" + data1 + "換出去");
					Thread.sleep((long) (Math.random() * 1000));
					String data2 = exchanger.exchange(data1);
					System.out.println("執行緒" + Thread.currentThread().getName() + "換回的資料為" + data2);
				}
				catch (Exception e)
				{
				}
			}
		});
	}
}
執行緒pool-1-thread-1正在把資料零食換出去
執行緒pool-1-thread-2正在把資料錢換出去
執行緒pool-1-thread-2換回的資料為零食
執行緒pool-1-thread-1換回的資料為錢


示例2
這個類在遇到類似生產者和消費者問題時,是非常有用的。來一個非常經典的併發問題:你有相同的資料buffer,一個或多個數據生產者,和一個或多個數據消費者。只是Exchange類只能同步2個執行緒,所以你只能在你的生產者和消費者問題中只有一個生產者和一個消費者時使用這個類。
public class Producer implements Runnable
{

	// 要被相互交換的資料型別。
	private List<String> buffer;

	// 用來同步 producer和consumer
	private final Exchanger<List<String>> exchanger;

	public Producer(List<String> buffer, Exchanger<List<String>> exchanger)
	{
		this.buffer = buffer;
		this.exchanger = exchanger;
	}

	public void run()
	{
		// 實現10次交換
		for (int i = 0; i < 10; i++)
		{
			buffer.add("第" + i + "次生產者的資料" + i);
			try
			{
				// 呼叫exchange方法來與consumer交換資料
				System.out.println("第" + i + "次生產者在等待.....");
				buffer = exchanger.exchange(buffer);
				System.out.println("第" + i + "次生產者交換後的資料:" + buffer.get(i));
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
}


public class Consumer implements Runnable
{
	// 用來相互交換
	private List<String> buffer;

	// 用來同步 producer和consumer
	private final Exchanger<List<String>> exchanger;

	public Consumer(List<String> buffer, Exchanger<List<String>> exchanger)
	{
		this.buffer = buffer;
		this.exchanger = exchanger;
	}

	public void run()
	{
		// 實現10次交換
		for (int i = 0; i < 10; i++)
		{
			buffer.add("第" + i + "次消費者的資料" + i);
			try
			{
				// 呼叫exchange方法來與consumer交換資料
				System.out.println("第" + i + "次消費者在等待.....");
				buffer = exchanger.exchange(buffer);
				System.out.println("第" + i + "次消費者交換後的資料:" + buffer.get(i));
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
}

public class Core
{
	public static void main(String[] args)
	{
		// 建立2個buffers,分別給producer和consumer使用
		List<String> buffer1 = new ArrayList<String>();
		List<String> buffer2 = new ArrayList<String>();

		// 建立Exchanger物件,用來同步producer和consumer
		Exchanger<List<String>> exchanger = new Exchanger<List<String>>();

		// 建立Producer物件和Consumer物件
		Producer producer = new Producer(buffer1, exchanger);
		Consumer consumer = new Consumer(buffer2, exchanger);

		// 建立執行緒來執行producer和consumer並開始執行緒
		Thread threadProducer = new Thread(producer);
		Thread threadConsumer = new Thread(consumer);
		threadProducer.start();
		threadConsumer.start();
	}
}
Exchanger 類有另外一個版本的exchange方法
exchange(V data, long time, TimeUnit unit)
V是宣告引數種類,例子中是List
此執行緒會休眠直到另一個執行緒到達並中斷它,或者特定的時間過去了
TimeUnit類有多種常量,DAYS、HOURS、MICROSECONDS、MILLISECONDS、MINUTES、NANOSECONDS和SECONDS

原帖地址:
http://blog.csdn.net/howlaa/article/details/19853447
http://ifeve.com/thread-synchronization-utilities-8/

相關推薦

java.util.concurrent(7)-Exchanger使用

Java 併發 API 提供了一種允許2個併發任務間相互交換資料的同步應用。更具體的說,Exchanger類允許在2個執行緒間定義同步點,當2個執行緒到達這個點,他們相互交換資料型別,使用第一個執行緒的資料型別變成第二個的,然後第二個執行緒的資料型別變成第一個的。示例1 一

Java基礎知識-java.util.concurrent下常見類的使用

finall iss con value 通信 out 否則 app ted 一,Condition 一個場景,兩個線程數數,同時啟動兩個線程,線程A數1、2、3,然後線程B數4、5、6,最後線程A數7、8、9,程序結束,這涉及到線程之間的通信。 public class

【JDK源碼】JDK的java.util.concurrent結構

cli 安全 出現 CA cat sun executor 並發 ML 本文從JDK源碼包中截取出concurrent包的所有類,對該包整體結構進行一個概述。 在JDK1.5之前,Java中要進行業務並發時,通常需要有程序員獨立完成代碼實現,當然也有一些開源的框架提供了這些

java.util.concurrent 下面的所有類

java.util.concurrent 包下面的所有類 原子運算元類: java.util.concurrent.atomic.AtomicBoolean.class java.util.concurrent.atomic.AtomicInteger.class java.ut

為什麼java.util.concurrent 裡沒有併發的ArrayList實現?

原文連結 作者:Stephen C 譯者:鄭旭東  校對:方騰飛 問:JDK 5在java.util.concurrent裡引入了ConcurrentHashMap,在需要支援高併發的場景,我們可以使用它代替HashMap。但是為什麼沒有ArrayList的併發實現呢?難道在多執行緒場景下我們

java.util.concurrent下同步輔助工具類CountDownLatch

        CountDownLatch作為一個輔助工具類,它允許一個或多個執行緒等待一系列指定操作的完成。CountDownLatch以一個給定值進行初始化,通過CountDownLatch cd

demo快取 refersh()可以用java.util.concurrent中的Executors.newSingleThreadScheduledExecutor定時器觸發

import java.util.List; public interface CacheService { List<OrderInfo> queryOrderInfoByCache(String userId); }   import com.goo

java.util.concurrent下的類 (轉)

文章整理來源:http://www.cnblogs.com/aurawing/articles/1887056.html 一 ,背景: 在JDK1.5之前,Java中要進行業務併發時,通常需要有程式設計師獨立完成程式碼實現,當然也有一些開源的框架提供了這些功能,但是這些依然沒有JDK自帶的功

java.util.concurrent詳細分析

概述 java.util.concurrent 包含許多執行緒安全、測試良好、高效能的併發構建塊。不客氣地說,建立java.util.concurrent 的目的就是要實現 Collection 框架對資料結構所執行的併發操作。通過提供一組可靠的、高效能併發構建塊,開發人員

執行緒併發執行緒安全介紹及java.util.concurrent下類介紹

執行緒Thread,在Java開發中多執行緒是必不可少的,但是真正能用好的並不多! 首先開啟一個執行緒三種方式  ①new Thread(Runnable).start()  ②thread.star

java.util.concurrent(2)-執行緒池

一、概述 java.util.concurrent中有非常方便的執行緒池實現,提供的Executor框架包含用於管理實現Runnable任務,Executors類提供了許多不同型別的Executor實現的靜態工廠方法。二、例項 public class MyTask implements Runnable {

java.util.concurrent中執行緒安全的集合簡介

一、執行緒安全的集合        Java中有很多支援多執行緒併發的集合,比如Hashtable、Vector但是這些“古老”的併發集合效率並不高,一般只支援一個執行緒對其進行讀寫(加鎖是針對整張表

java.util.concurrent下的幾個常用類

1.Callable<V> Callable<V>與Runnable類似,理解Callable<V>可以從比較其與Runnable的區別開始: 1)從使用上:實現的Callable<V>的類需要實現call()方法,此方

【一】關於java.util.concurrent下的併發類(atomic)

併發類包除了java.util.concurrent之外,還有java.util.concurrent.atomic和java.util.concurrent.lock.java.util.concurrent中主要是一些關於集合框架的併發實現,例如ConcurrentHas

java.util.concurrent(3)-執行緒間通訊wait/notify和await/signal

1 wait和notify 當呼叫wait()方法時執行緒會放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件呼叫notify()方法後本執行緒才進入物件鎖定池準備 Object的方法:void notify(): 喚醒一個正在等待該物件的執行緒。void noti

java.util.concurrent 中Executor與Executors的區別

1、Executor是Java執行緒池的頂級介面 Executor類的繼承關係:        備註:ScheduledExecutorService描述的功能和Timer/TimerTask類似,解決那些需要任務重複執行的問題。這包括延遲時間一次性執行、延遲時間

java.util.concurrent中執行緒池Executors的使用

執行緒池的概念與Executors類的使用 (1)建立固定大小的執行緒池–當有多個任務時,會先按照執行緒池中的資料執行任務,其他任務處於等待過程中,等執行完這批任務後再執行下批任務。 (2)建立快

Java多執行緒與高併發:java.util.concurrent

面試官:你用過JUC的哪些工具類? 前面從基礎開始,到執行緒安全的實現、物件的釋出與共享,涉及到很多執行緒安全的類與工具,JDK1

java.util.Concurrent

java.util.concurrent併發程式設計包是專門為Java併發程式設計設計的,其中設計的類主要分為以下幾部分:

Java 併發工具-java.util.concurrent-原始碼jdk1.7全面解析

先來看看類圖: 其實從類圖我們能發現concurrent包(除去java.util.concurrent.atomic 和 java.util.concurrent.locks)中的內容並沒有特別多,大概分為四類:BlockingQueue阻塞佇列體系、Executor