Java多執行緒之Condition
Condition,Condition 將 Object 監視器方法(wait、notify 和 notifyAll)分解成截然不同的物件,以便通過將這些物件與任意 Lock 實現組合使用,為每個物件提供多個等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和語句的使用,Condition 替代了 Object 監視器方法的使用。下面將之前寫過的一個執行緒通訊的例子替換成用Condition實現(Java執行緒(三)),程式碼如下:
public class ThreadTest2 {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
threadExecute(business, "sub");
}
}).start();
threadExecute(business, "main");
}
public static void threadExecute(Business business, String threadType) {
for (int i = 0; i < 100; i++) {
try {
if("main".equals(threadType)) {
business.main(i);
} else {
business.sub(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Business {
private boolean bool = true;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public /*synchronized*/ void main(int loop) throws InterruptedException {
lock.lock();
try {
while(bool) {
condition.await();//this.wait();
}
for(int i = 0; i < 100; i++) {
System.out.println("main thread seq of " + i + ", loop of " + loop);
}
bool = true;
condition.signal();//this.notify();
} finally {
lock.unlock();
}
}
public /*synchronized*/ void sub(int loop) throws InterruptedException {
lock.lock();
try {
while(!bool) {
condition.await();//this.wait();
}
for(int i = 0; i < 10; i++) {
System.out.println("sub thread seq of " + i + ", loop of " + loop);
}
bool = false;
condition.signal();//this.notify();
} finally {
lock.unlock();
}
}
}
在Condition中,用await()替換wait(),用signal()替換notify(),用signalAll()替換notifyAll(),傳統執行緒的通訊方式,Condition都可以實現,這裡注意,Condition是被繫結到Lock上的,要建立一個Lock的Condition必須用newCondition()方法。
這樣看來,Condition和傳統的執行緒通訊沒什麼區別,Condition的強大之處在於它可以為多個執行緒間建立不同的Condition,下面引入API中的一段程式碼,加以說明。
class BoundedBuffer {
final Lock lock = new ReentrantLock();//鎖物件
final Condition notFull = lock.newCondition();//寫執行緒條件
final Condition notEmpty = lock.newCondition();//讀執行緒條件
final Object[] items = new Object[100];//快取佇列
int putptr/*寫索引*/, takeptr/*讀索引*/, count/*佇列中存在的資料個數*/;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)//如果佇列滿了
notFull.await();//阻塞寫執行緒
items[putptr] = x;//賦值
if (++putptr == items.length) putptr = 0;//如果寫索引寫到佇列的最後一個位置了,那麼置為0
++count;//個數++
notEmpty.signal();//喚醒讀執行緒
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)//如果佇列為空
notEmpty.await();//阻塞讀執行緒
Object x = items[takeptr];//取值
if (++takeptr == items.length) takeptr = 0;//如果讀索引讀到佇列的最後一個位置了,那麼置為0
--count;//個數--
notFull.signal();//喚醒寫執行緒
return x;
} finally {
lock.unlock();
}
}
}
這是一個處於多執行緒工作環境下的快取區,快取區提供了兩個方法,put和take,put是存資料,take是取資料,內部有個快取佇列,具體變數和方法說明見程式碼,這個快取區類實現的功能:有多個執行緒往裡面存資料和從裡面取資料,其快取佇列(先進先出後進後出)能快取的最大數值是100,多個執行緒間是互斥的,當快取佇列中儲存的值達到100時,將寫執行緒阻塞,並喚醒讀執行緒,當快取佇列中儲存的值為0時,將讀執行緒阻塞,並喚醒寫執行緒,這也是ArrayBlockingQueue的內部實現。下面分析一下程式碼的執行過程:
1. 一個寫執行緒執行,呼叫put方法;
2. 判斷count是否為100,顯然沒有100;
3. 繼續執行,存入值;
4. 判斷當前寫入的索引位置++後,是否和100相等,相等將寫入索引值變為0,並將count+1;
5. 僅喚醒讀執行緒阻塞佇列中的一個;
6. 一個讀執行緒執行,呼叫take方法;
7. ……
8. 僅喚醒寫執行緒阻塞佇列中的一個。
這就是多個Condition的強大之處,假設快取佇列中已經存滿,那麼阻塞的肯定是寫執行緒,喚醒的肯定是讀執行緒,相反,阻塞的肯定是讀執行緒,喚醒的肯定是寫執行緒,那麼假設只有一個Condition會有什麼效果呢,快取佇列中已經存滿,這個Lock不知道喚醒的是讀執行緒還是寫執行緒了,如果喚醒的是讀執行緒,皆大歡喜,如果喚醒的是寫執行緒,那麼執行緒剛被喚醒,又被阻塞了,這時又去喚醒,這樣就浪費了很多時間。
本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7481142,轉載請註明。
相關推薦
Java多執行緒之Condition實現原理和原始碼分析(四)
章節概覽、 1、概述 上面的幾個章節我們基於lock(),unlock()方法為入口,深入分析了獨佔鎖的獲取和釋放。這個章節我們在此基礎上,進一步分析AQS是如何實現await,signal功能。其功能上和synchronize的wait,notify一樣。
Java多執行緒之Condition
Condition,Condition 將 Object 監視器方法(wait、notify 和 notifyAll)分解成截然不同的物件,以便通過將這些物件與任意 Lock 實現組合使用,為每個物件提供多個等待 set (wait-set)。其中,Lock 替
java多執行緒之ReentrantLock和 Condition
ReentrantLock 是JDK中內建鎖,也稱可重入鎖,API也較為簡單。 Condition 可實現 執行緒間通訊,由ReentrantLock 例項產生即 lock.new Condition(); 下面這個demo模擬最簡單的生產者 消費者模式,Add執行緒模
Java多執行緒之JUC包:Condition原始碼學習筆記
若有不正之處請多多諒解,並歡迎批評指正。 請尊重作者勞動成果,轉載請標明原文連結: Condition在JUC框架下提供了傳統Java監視器風格的wait、notify和notifyAll相似的功能。 Condition必須被繫結到一個獨佔鎖上使用。ReentrantLock中獲取Conditi
JAVA多執行緒之——執行緒通訊 Condition
執行緒的通訊 前面學習了用wait/notify的方式進行執行緒通訊。今天學習一種更加強大的執行緒通訊方式Condition.Condition的強大之處就是可以為執行緒建立不同的Condition。然後可以喚醒任意指定阻塞的執行緒。Condition之所以能
Java多執行緒之執行緒併發庫條件阻塞Condition的應用
鎖(Lock/synchronized)只能實現互斥不能實現通訊,Condition的功能類似於在傳統的執行緒技術中的,Object.wait()和Object.notify()的功能,在等待Condition時,允許發生"虛假喚醒",這通常作為對基礎平臺語義的讓步,對於大多
Java多執行緒之join()方法
概要 本章,會對Thread中join()方法進行介紹。涉及到的內容包括: 1. join()介紹 2. join()原始碼分析(基於JDK1.7.0_40) 3. join()示例 來源:http://www.cnblogs.com/skywang12345/p/34792
白話理解java多執行緒之join()方法
join字面意思是加入,我理解為插隊. 舉例:媽媽在炒菜,發現沒喲醬油了,讓兒子去打醬油,兒子打完醬油,媽媽炒完菜,全家一起吃 package cn.yh.thread01; /** * * 打醬油的例子 */ public class Demo03 { public stat
細說Java 多執行緒之記憶體可見性
前言: 討論學習Java中的記憶體可見性、Java記憶體模型、指令重排序、as-if-serial語義等多執行緒中偏向底層的一些知識,以及synchronized和volatile實現記憶體可見性的原理和方法。 1、可見性介紹 可見性:一個執行緒對共用變數值的修改,能夠及時地被其他執行緒
java多執行緒之 執行緒協作
也是網上看的一道題目:關於假如有Thread1、Thread2、Thread3、Thread4四條執行緒分別統計C、D、E、F四個盤的大小,所有執行緒都統計完畢交給Thread5執行緒去做彙總,應當如何實現? 蒐集整理了網上朋友提供的方法,主要有: 1. 多執行緒都是Thread或
java多執行緒之鎖機制二
網上看到一個題目,題目是這樣:Java多執行緒,啟動四個執行緒,兩個執行加一,另外兩個執行減一。 針對該問題寫了一個程式,測試通過,如下: class Sync { static int count = 0; public void add() {
java多執行緒之鎖機制一
網上看了一篇關於java synchronized關鍵字使用的很好的文章,現將其簡要總結一下,加深理解。 先總結兩個規則: synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。 多個執行緒
java多執行緒之Phaser
java多執行緒技術提供了Phaser工具類,Phaser表示“階段器”,用來解決控制多個執行緒分階段共同完成任務的情景問題。其作用相比CountDownLatch和CyclicBarrier更加靈活,例如有這樣的一個題目:5個學生一起參加考試,一共有三道題,要求所有學生到齊才能開始考試,全部同學都
Java多執行緒之——ThreadLocal
ThreadLocal是什麼:每一個ThreadLocal能夠放一個執行緒級別的變數,也就是說,每一個執行緒有獨自的變數,互不干擾。以此達到執行緒安全的目的,並且一定會安全。 實現原理: 要了解實現原理,我們先看set方法 public void set(T value) { T
java多執行緒之Lock--顯式鎖
Lock與Synchronized簡介 Synchornized相信大家用的已經比較熟悉了,這裡我就不介紹它的用法了 Synchronized被稱為同步鎖或者是隱式鎖,隱式鎖與顯式鎖區別在於,隱式鎖的獲取和釋放都需要出現在一個塊結構中,而且是有順序的,獲取鎖的順序和釋放鎖的順序必須相反,就是說,
Java多執行緒之Executor框架
在前面的這篇文章中介紹了執行緒池的相關知識,現在我們來看一下跟執行緒池相關的框架--Executor。 一.什麼是Executor 1.Executor框架的兩級排程模型 在HotSpot VM的執行緒模型中,Java執行緒(java.lang.Thread)被一對一對映為本地作業系統執
java多執行緒之Executor
程式 程序:執行的程式 執行緒:程序中負責程式執行的執行單元,一個程序至少包括一個執行緒。 單執行緒:一個程序一個執行緒 多執行緒:一個程序多個執行緒 多執行緒是為了更好的利用CPU,提高程式執行的速度。 實現方式:繼承Thread類、實現Runnabl
Java多執行緒學習---Condition和wait、notify(十三)
1.問題:實現兩個執行緒交叉執行(Condition和wait、notify都可以實現) public class ConditionStudy { public static void main(String[] args) { //執行緒程式碼 BussinessTes
java多執行緒之(二)鎖
一,鎖 在物件的建立時java會為每個object物件分配一個monitor( 監視器或者監視鎖),當某個物件的同步方法(synchronized methods )被多個執行緒呼叫時,該物件的monitor將負責處理這些訪問的併發獨佔要求。 當一個執行緒呼叫一個物件的同步方法時(sy
Java多執行緒之鎖優化策略
轉載 http://www.cnblogs.com/ygj0930/p/6561264.html 編碼過程中可採取的鎖優化的思路有以下幾種: 1:減少鎖持有時間 例如:對一個方法加鎖,不如對方法中需要同步的幾行程式碼加鎖; 2:減小鎖粒度 例如: