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...