synchronized和lock的區別簡介

2021-10-08 01:25:53 字數 3857 閱讀 9169

​ synchronized:在需要同步的物件中加入此控制,synchronized可以加在方法上,也可以加在特定**塊中,括號中表示需要鎖的物件。

​ lock:需要顯示指定起始位置和終止位置。一般使用reentrantlock類做為鎖,多個執行緒中必須要使用乙個reentrantlock類做為物件才能保證鎖的生效。且在加鎖和解鎖處需要通過lock()和unlock()顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。

lock():獲取鎖,如果鎖被暫用則一直等待

unlock():釋放鎖

trylock(): 注意返回型別是boolean,如果獲取鎖的時候鎖被占用就返回false,否則返回true

trylock(long time, timeunit unit):比起trylock()就是給了乙個時間期限,保證等待引數時間

lockinterruptibly():用該鎖的獲得方式,如果執行緒在獲取鎖的階段進入了等待,那麼可以中斷此執行緒,先去做別的事

lock的使用**如下:

public

class

lockdemo

catch

(exception e)

finally

}public

static

void

main

(string[

] args)},

"t1");

thread t2 =

newthread

(new

runnable()

},"t2");

t1.start()

; t2.

start();}}

執行結果:

執行緒名t1獲得了鎖

執行緒名t1釋放了鎖

執行緒名t2獲得了鎖

執行緒名t2釋放了鎖

trylock的使用:

public

class

trylock

catch

(exception e)

finally

}else

}public

static

void

main

(string[

] args)},

"t1");

//執行緒2

thread t2 =

newthread

(new

runnable()

},"t2");

t1.start()

; t2.

start();}}

執行結果:

執行緒名t1獲得了鎖

執行緒名t1釋放了鎖

我是t2有人佔著鎖,我就不要啦

關於trylock(long time, timeunit unit)和lock.interruptibly()。前者主要存在乙個等待時間,在測試**中寫入乙個等待時間,後者主要是等待中斷,會丟擲乙個中斷異常。

try

else

}catch

(exception e)

}

reentrantlock可以與condition的配合使用,condition為reentrantlock鎖的等待和釋放提供控制邏輯;

使用reentrantlock加鎖之後,可以通過它自身的condition.await()方法釋放該鎖,執行緒在此等待condition.signal()方法,然後繼續執行下去。await方法需要放在while迴圈中,因此,在不同執行緒之間實現併發控制,還需要乙個volatile的變數,boolean是原子性的變數。

/**

* 子執行緒迴圈2次,接著主線程迴圈4次,

* 接著又回到子執行緒迴圈2次,接著再回到主線程又迴圈4次,如此迴圈5次

*/public

class

conditiondemo

for(

int j =

0; j <

2; j++

) subflag =

true

; subcondition.

signal()

;}catch

(exception e)

finally}}

}); threadpool.

shutdown()

;for

(int i =

0; i <

5; i++

)for

(int j =

0; j <

4; j++

) subflag =

false

; subcondition.

signal()

;}catch

(exception e)

finally}}

}

synchronized的簡單使用:

public

class

thread1

extends

thread

// 給執行緒名字賦值

static

int i =10;

// 建立乙個靜態鑰匙

static object ob =

"lock"

;//值是任意的

// 重寫run方法,實現買票操作

@override

public

void

run(

)else

}try

catch

(interruptedexception e)}}

}

區別如下:異常是否釋放鎖:

synchronized在發生異常時候會自動釋放占有的鎖,因此不會出現死鎖;而lock發生異常時候,不會主動釋放占有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發生。(所以最好將同步**塊用try catch包起來,finally中寫入unlock,避免死鎖的發生。)

是否響應中斷

lock等待鎖過程中可以用interrupt來中斷等待,而synchronized只能等待鎖的釋放,不能響應中斷;

是否知道獲取鎖

lock可以通過trylock來知道有沒有獲取鎖,而synchronized不能;

lock可以提高多個執行緒進行讀操作的效率。(可以通過readwritelock實現讀寫分離)

在效能上來說,如果競爭資源不激烈,兩者的效能是差不多的,而當競爭資源非常激烈時(即有大量執行緒同時競爭),此時lock的效能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。

synchronized使用object物件本身的wait 、notify、notifyall排程機制,而lock可以使用condition進行執行緒之間的排程,

synchronized原語和reentrantlock在一般情況下沒有什麼區別,但是在非常複雜的同步應用中,請考慮使用reentrantlock,特別是遇到下面2種需求的時候。

1.某個執行緒在等待乙個鎖的控制權的這段時間需要中斷

2.需要分開處理一些wait-notify,reentrantlock裡面的condition應用,能夠控制notify哪個執行緒

ed使用object物件本身的wait 、notify、notifyall排程機制,而lock可以使用condition進行執行緒之間的排程,

lockInterruptibly和lock的區別

size medium lock 拿不到lock就不罷休,不然執行緒就一直block。lockinterruptibly會優先響應執行緒中斷,處理響應的方式是丟擲interruptedexception。size 可以從原始碼看出來的 private void doacquireinterrupti...

synchronized和volatile的區別?

一旦乙個共享變數 類的成員變數 類的靜態成員變數 被volatile修飾之後,那麼就具備了兩層語義 1 保證了不同執行緒對這個變數進行操作時的可見性,即乙個執行緒修改了某個變數的值,這新值對其他執行緒來說是 立即可見的。2 禁止進行指令重排序。volatile本質是在告訴jvm當前變數在暫存器 工作...

synchronized和volatile的區別

volatile關鍵字的本質是告訴jvm,該變數在暫存器中的值是不確定的,需要在主存中讀取,而synchronized關鍵字是鎖住當前變數,只有當前執行緒可以訪問,其他執行緒等待。volatile關鍵字的作用 保證變數的可見性和防止指令重排序。1.volatile只能作用於變數,而synchroni...