多執行緒與併發-----條件阻塞Condition的應用
Condition
1、 功能:
其類似在傳統執行緒技術中的 Object.wait() 和 Object.notify() 的功能,傳統執行緒技術實現互斥只能是一個執行緒單獨幹,不能說這個執行緒幹完了通知另一個執行緒來幹,Condition就是解決這個問題:實現執行緒間的通訊。比如CPU讓小弟做事,小弟說我先歇著,並通知大哥,大哥開始做事。
public interface Condition
Condition 將 Object監視器方法(wait、notify和notifyAll)分解成截然不同的物件,以便通過將這些物件與任意Lock實現組合使用,為每個物件提供多個等待set(wait-set)。其中,Lock替代了 synchronized 方法和語句的使用,Condition替代了 Object 監視器方法的使用。
2、 實質:
實質上是被繫結到一個鎖上。要為特定的 Lock 例項獲得 Condition 例項,請使用 new Condition()方法。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ConditionCommunication { public static void main(String[] args) { final Business business=new Business(); new Thread(new Runnable() { public void run() { for(int i=0;i<50;i++){ business.sub(i); } } }).start(); for(int i=0;i<50;i++){ business.main(i); } } static class Business{ Lock lock=new ReentrantLock(); Condition condition=lock.newCondition(); private boolean bSholdSub=true; public void sub(int i){ lock.lock(); try{ while(!bSholdSub){ try { //this.wait(); condition.await(); } catch (Exception e) { e.printStackTrace(); } } for(int j=0;j<10;j++){ System.out.println("sub thread sequence of"+j+",loop of"+i); } bSholdSub=false; condition.signal(); //this.notify();//notify必須和synchronized一起用 }finally{ lock.unlock(); } } public void main(int i){ lock.lock(); try{ while(bSholdSub){ try { //this.wait(); condition.await(); } catch (Exception e) { e.printStackTrace(); } } for(int j=0;j<10;j++){ System.out.println("main thread sequence of"+j+",loop of"+i); } bSholdSub=true; //this.notify(); condition.signal(); }finally{ lock.unlock(); } } } }
執行結果為:
sub thread sequence of0,loop of0
sub thread sequence of1,loop of0
sub thread sequence of2,loop of0
sub thread sequence of3,loop of0
sub thread sequence of4,loop of0
sub thread sequence of5,loop of0
sub thread sequence of6,loop of0
sub thread sequence of7,loop of0
sub thread sequence of8,loop of0
sub thread sequence of9,loop of0
main thread sequence of0,loop of0
main thread sequence of1,loop of0
main thread sequence of2,loop of0
main thread sequence of3,loop of0
main thread sequence of4,loop of0
main thread sequence of5,loop of0
main thread sequence of6,loop of0
main thread sequence of7,loop of0
main thread sequence of8,loop of0
main thread sequence of9,loop of0
3、例項---可阻塞佇列
假定有一個繫結的緩衝區,它支援 put 和 take 方法。如果試圖在空的緩衝區上執行 take 操作,則在某一個項變得可用之前,執行緒將一直阻塞;如果試圖在滿的緩衝區上執行 put 操作,則在有空間變得可用之前,執行緒將一直阻塞。我們喜歡在單獨的等待 set 中儲存 put 執行緒和 take 執行緒,這樣就可以在緩衝區中的項或空間變得可用時利用最佳規劃,一次只通知一個執行緒。可以使用兩個 Condition 例項來做到這一點。
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; ++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; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
使用方法:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
this.wait()----》condition.await()
this.notify()----》condition.signal()
注意:判斷條件時用while防止虛假喚醒,等待在那裡,喚醒後再進行判斷,確認符合要求後再執行任務。
例項:
有三個執行緒,主執行緒10次,第一個子執行緒10次,第二個子執行緒10次迴圈執行50次。用Condition方法實現
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreeConditionCommunication {
public static void main(String[] args) {
final Business business=new Business();
new Thread(new Runnable() {
public void run() {
for(int i=0;i<10;i++){
business.sub1(i);
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for(int i=0;i<20;i++){
business.sub2(i);
}
}
}).start();
for(int i=0;i<50;i++){
business.main(i);
}
}
static class Business{
Lock lock=new ReentrantLock();
Condition condition1=lock.newCondition();
Condition condition2=lock.newCondition();
Condition condition3=lock.newCondition();
//private boolean bSholdSub=true;
private int shouldsub=1;
public void sub1(int i){
lock.lock();
try{
while(shouldsub!=2){
try {
//this.wait();
condition2.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for(int j=0;j<10;j++){
System.out.println("sub1 thread sequence of"+j+",loop of"+i);
}
//bSholdSub=false;
//condition.signal();
shouldsub=3;
condition3.signal();
//this.notify();//notify必須和synchronized一起用
}finally{
lock.unlock();
}
}
public void sub2(int i){
lock.lock();
try{
while(shouldsub!=3){
try {
//this.wait();
condition3.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for(int j=0;j<10;j++){
System.out.println("sub2 thread sequence of"+j+",loop of"+i);
}
/*bSholdSub=false;
condition.signal();*/
shouldsub=1;
condition1.signal();
//this.notify();//notify必須和synchronized一起用
}finally{
lock.unlock();
}
}
public void main(int i){
lock.lock();
try{
while(shouldsub!=1){
try {
//this.wait();
condition1.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for(int j=0;j<10;j++){
System.out.println("main thread sequence of"+j+",loop of"+i);
}
/*bSholdSub=true;
//this.notify();
condition.signal();*/
shouldsub=2;
condition2.signal();
}finally{
lock.unlock();
}
}
}
}
執行結果為:
main thread sequence of0,loop of0
main thread sequence of1,loop of0
main thread sequence of2,loop of0
main thread sequence of3,loop of0
main thread sequence of4,loop of0
main thread sequence of5,loop of0
main thread sequence of6,loop of0
main thread sequence of7,loop of0
main thread sequence of8,loop of0
main thread sequence of9,loop of0
sub1 thread sequence of0,loop of0
sub1 thread sequence of1,loop of0
sub1 thread sequence of2,loop of0
sub1 thread sequence of3,loop of0
sub1 thread sequence of4,loop of0
sub1 thread sequence of5,loop of0
sub1 thread sequence of6,loop of0
sub1 thread sequence of7,loop of0
sub1 thread sequence of8,loop of0
sub1 thread sequence of9,loop of0
sub2 thread sequence of0,loop of0
sub2 thread sequence of1,loop of0
sub2 thread sequence of2,loop of0
sub2 thread sequence of3,loop of0
sub2 thread sequence of4,loop of0
sub2 thread sequence of5,loop of0
sub2 thread sequence of6,loop of0
sub2 thread sequence of7,loop of0
sub2 thread sequence of8,loop of0sub2 thread sequence of9,loop of0
......
相關文章
- 多執行緒中使用Lock鎖定多個條件Condition的使用執行緒
- Python執行緒條件變數Condition解析Python執行緒變數
- 程式與執行緒、同步與非同步、阻塞與非阻塞、併發與並行執行緒非同步並行
- 多執行緒與高併發(二)執行緒安全執行緒
- 併發與多執行緒之執行緒安全篇執行緒
- 多執行緒與高併發(一)多執行緒入門執行緒
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- 多執行緒併發篇——三件兵器執行緒
- 多執行緒與併發----Semaphere同步執行緒
- 併發與多執行緒基礎執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- java多執行緒與併發 - 併發工具類Java執行緒
- 多執行緒06:條件變數執行緒變數
- 【多執行緒與高併發】- 執行緒基礎與狀態執行緒
- 程式執行緒、同步非同步、阻塞非阻塞、併發並行執行緒非同步並行
- 多執行緒與併發----讀寫鎖執行緒
- Java多執行緒與併發之ThreadLocalJava執行緒thread
- Java高併發與多執行緒(二)-----執行緒的實現方式Java執行緒
- 用多執行緒,實現併發,TCP執行緒TCP
- 併發條件佇列之Condition 精講佇列
- JAVA多執行緒併發Java執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- 多執行緒應用–Http請求阻塞回撥處理執行緒HTTP
- 多執行緒應用--Http請求阻塞回撥處理執行緒HTTP
- 併發-0-同步/非同步/阻塞/非阻塞/程式/執行緒非同步執行緒
- 多執行緒應用執行緒
- 非同步/同步,阻塞/非阻塞,單執行緒/多執行緒概念梳理非同步執行緒
- 多執行緒與併發-----Lock鎖技術執行緒
- 【多執行緒與高併發】- 淺談volatile執行緒
- Java高併發與多執行緒(一)-----概念Java執行緒
- 【多執行緒與高併發 2】volatile 篇執行緒
- Java BlockingQueue 阻塞佇列[用於多執行緒]JavaBloC佇列執行緒
- Java併發指南1:併發基礎與Java多執行緒Java執行緒
- 深入解析 TiFlash丨多併發下執行緒建立、釋放的阻塞問題執行緒
- 【多執行緒與高併發】從一則招聘資訊進入多執行緒的世界執行緒
- 執行緒的讓步與阻塞執行緒
- java多執行緒:執行緒池原理、阻塞佇列Java執行緒佇列
- 多執行緒與併發----CycliBarrier、CountDownLatch 和 Exchanger同步執行緒CountDownLatch