synchronized
如果在同一個(gè)對(duì)象上,不同線程調(diào)用了不同的synchronized方法,方法的調(diào)用也是串行的,
比如線程1先調(diào)用對(duì)象obj的synchronized的方法A,線程2調(diào)用了同一個(gè)對(duì)象obj的synchronized的方法B。
線程1先執(zhí)行完方法A,線程2才輪到執(zhí)行方法B。盡管這兩個(gè)不是同一個(gè)方法。
package com.concurrent.demo;
class Sync{
public synchronized void func1(){
System.out.println("func1 begins");
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("func1 ends");
}
public synchronized void func2(){
for(int i =0;i<10;i++){
System.out.println("func2");
}
}
}
public class SyncDemo {
public static void main(String[] args) {
Sync obj = new Sync();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
obj.func1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
obj.func2();
}
});
t1.start();
t2.start();
}
}
輸出
func1 begins
func1 ends
func2
func2
func2
func2
func2
func2
func2
func2
func2
func2
如果去掉func2的synchronized關(guān)鍵字,那么func2就不用等待func1執(zhí)行完了。
問題1:對(duì)于非靜態(tài)方法,synchronized針對(duì)的是同一個(gè)對(duì)象嗎?
是的。每一個(gè)對(duì)象有一個(gè)內(nèi)部鎖, 并且該鎖有一個(gè)內(nèi)部條件。 由鎖來管理那些試圖進(jìn)入 synchronized 方法的線程, 由條件來管理那些調(diào)用 wait 的線程。
Java 中的每一個(gè)對(duì)象都有一個(gè)內(nèi)部鎖。
每一個(gè)java對(duì)象有內(nèi)在鎖,intrinsic lock
調(diào)用synchronized修飾的方法時(shí),線程必須取得該對(duì)象的內(nèi)在鎖。
內(nèi)部對(duì)象鎖只有一個(gè)相關(guān)條件。wait 方法添加一個(gè)線程到等待集中, notifyAll /notify 方法解除等待線程的阻塞狀態(tài)。 換句話說, 調(diào)用 wait 或 notityAll 等價(jià)于
intrinsicCondition.await();
intrinsicCondition.signal();
問題2:為什么需要Condition?
因?yàn)槟惬@取了鎖之后,執(zhí)行時(shí)發(fā)現(xiàn)某個(gè)條件不滿足,要等待條件滿足了才能往下繼續(xù)執(zhí)行,但這個(gè)線程獲得鎖之后其他線程想執(zhí)行這段代碼是無法操作的,這時(shí)候需要釋放鎖。通過條件對(duì)象,釋放鎖并且進(jìn)入阻塞狀態(tài)。