首先我們回顧下同步**塊,例如:
object obj = new
object();
void show()
}
同步**塊對鎖的操作是隱式的,執行完同步**塊中的內容,自動釋放鎖。而lock將鎖封裝成為了物件,即把對鎖操作的隱式操作換成了顯示操作。可以將如上**改寫:
lock
lock = new reentrantlock();
void show()
jdk1.5之後將同步和鎖封裝成了物件,並將操作鎖的隱式方式定義到了該物件中,將隱式動作變成了顯示動作。
上述**中存在隱患,例如code部門產生異常throw exception的話,會導致後面**無法執行,即沒有釋放鎖,因此需要將釋放鎖的操作放在finally塊中。
lock lock = new reentrantlock();
void show()finally
}
condition newcondition():返回繫結到此lock例項的新condition例項
public inte***ce condition ,condition將object監視器方法(wait,notify和notifyall)分解成截然不同的物件,以便通過將這些物件與任意lock實現組合使用,為每個物件提供多個等待set(wait-set)。其中,lock替代了synchronized方法和語句的使用,condition替代了object監視器方法的使用。
條件(也稱為條件佇列或條件變數)為執行緒提供乙個含義,以便在某個狀態條件現在可能為true的另乙個執行緒通知它之前,一直掛起該執行緒(即讓其「等待」)。因為訪問此共享狀態資訊發生在不同的執行緒中,所以它必須受保護,因此要將某種形式的鎖與該條件相關聯。等待提供乙個條件的主要屬性是:以原子方式釋放相關的鎖,並掛起當前執行緒,就像object.wait做的那樣。
condition例項實質上被繫結到乙個鎖上。要為特定lock例項獲得condition例項,請使用其newcondition()方法。
具體是什麼意思呢,個人用自己的理解白話解釋下:
正常的傳統synchronized塊方式,每個鎖物件obj對應有一套*wait,notify,notifyall方法(因為不同鎖物件的wait和notify是不起作用的),而condition對wait,notify,notifyall方法進行了封裝,多個condition物件可以同時所屬於同乙個lock鎖物件*
傳統方式:
class
object
class
demo
extends
object
demo d = new demo();
synchronized(d)
condition方式:
inte***ce condition
lock lock = new reentrantlock();
condition c1 = lock.newcondition();//根據鎖物件lock獲取一組監視器物件
condition c2 = lock.newcondition();//第二組監視器
由上可以發現lock的目的是為了替代同步,condition的目的是為了替代object中的方法
class
resourcedemocatch (interruptedexception e)
}this.name = name + count;
count++;
system.out.println(thread.currentthread().getname()+"...生產者..."+this.name);
flag = true;
//notifyall();
con.signalall();
}finally
}//消費者
public
void out()catch (interruptedexception e)
}system.out.println(thread.currentthread().getname()+"......消費者......"+this.name);
flag = false;
//notifyall();
con.signalall();
}finally
}}//生產者
class
producer
implements
runnable
public
void run()
}}//消費者
class
consumer
implements
runnable
public
void run()
}}public
class
producerconsumerdemo
}
注意點:
具體原因解釋可以參見之前部落格:
使用兩個監視器,一組監視生產者,一組監視消費者,而之前的傳統方法要想實現,需要兩個鎖,因為傳統方式一把鎖上只有一組監視器,而lock的方式,一把鎖上可以繫結多組監視器。因此可以實現「喚醒對方執行緒」,解決了之前傳統方法notifyall方式的效率低的問題。
class resourcedemocatch (interruptedexception e)
}this.name = name + count;
count++;
system.out.println(thread.currentthread().getname()+"...生產者..."+this.name);
flag = true;
//notifyall();
consumer_con.signalall();
}finally
}//消費者
public
void
out()catch (interruptedexception e)
}system.out.println(thread.currentthread().getname()+"......消費者......"+this.name);
flag = false;
//notifyall();
producer_con.signalall();
}finally
}}//生產者
class producer implements runnable
public
void
run()
}}//消費者
class consumer implements runnable
public
void
run()
}}public
class producerconsumerdemo
}
Python學習筆記 多執行緒鎖
多執行緒的鎖 如果有多個執行緒同時操作乙個物件,如果沒有很好地保護該物件,會造成程式結果的不可預期 多執行緒中,所有變數都由所有執行緒共享,所以,任何乙個變數都可以被任何乙個執行緒修改,因此,執行緒之間共享資料最大的危險在於多個執行緒同時改乙個變數,把內容給改亂了。因此需要用鎖threading.l...
多執行緒程式設計學習筆記(六)
多執行緒程式設計學習筆記 六 執行緒區域性儲存 tls 存放區域性儲存步驟 1 申請資料槽 localdatastoreslot slot thread.getnameddataslot para 如果不存在名為para的資料槽,將分配乙個所有執行緒均可用的para資料槽 2 往資料槽存放資料 my...
C 多執行緒學習 六 互斥物件
如何控制好多個執行緒相互之間的聯絡,不產生衝突和重複,這需要用到互斥物件,即 system.threading 命名空間中的 mutex 類。我們可以把mutex看作乙個計程車,乘客看作執行緒。乘客首先等車,然後上車,最後下車。當乙個乘客在車上時,其他乘客就只有等他下車以後才可以上車。而執行緒與mu...