Lock接口出現的背景:
- synchronized的缺陷:
1、阻塞式:當某一個線程獲取鎖時,並執行該代碼塊,其他線程只能夠一直等待,等待取鎖的線程釋放鎖;
2、效率底:一但線程執行sleep,其他線程只能乾巴巴的等待,一旦大量併發進入,將會極大影響性能;
3、釋放鎖:只有兩種情況:a.當前線程執行完畢。 b.線程執行異常,JVM自動釋放鎖;- Lock鎖的優勢:
1、Lock 是一個類,通過這個類可以實現同步訪問;
2、Lock 爲非內置鎖,可根據具體業務控制,但必須要用戶去手動釋放鎖,如果沒有主動釋放鎖,就有可能導致出現死鎖現象。
ReentrantLock
ReentrantLock是唯一實現Lock接口類,又名:併發鎖、嘗試鎖、定時鎖,以下是ReentrantLock的具體使用:
package com.cn.seesun2012.demo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 併發鎖 示例
* @author csdn:seesun2012
**/
public class TestLock {
// 定義全局變量(如果是局部將不起作用)
private Lock lock = new ReentranLock();
// 普通鎖
public String testLock() {
// 阻塞,其他線程一直處於等待,直到當前線程釋放鎖
lock.lock();
try {
// 業務代碼...
}catch(Exception ex){
// 異常處理...
}finally{
// 釋放鎖...
lock.unlock();
}
}
// 嘗試鎖
public String testTryLock(){
try {
// 不等待,嘗試過沒有獲取到鎖就直接返回false
if(lock.tryLock()) {
// 業務代碼...
} else {
// 沒有獲取到鎖,做其他事情...
}
} catch (Exception e) {
// 異常處理...
} finally {
// 釋放鎖...
lock.unlock();
}
}
// 嘗試 + 定時 鎖
public String testTimeTryLock(){
try {
// 等待,如果沒有獲取鎖等待3秒,SECONDS代表:秒,3秒後仍然沒有獲取返回false
if(lock.tryLock(3, TimeUnit.SECONDS)) {
// 業務代碼...
Thread.sleep(2l); // 模擬訪問數據庫
} else{
// 沒有獲取到鎖,做其他事情...
}
} catch (Exception e) {
// 異常處理...
} finally {
// 釋放鎖...
lock.unlock();
}
}
// 測試啓動程序
public static void main(String[] args) {
final TestLock testLock= new TestLock();
new Thread(){
public void run() {
testLock.testTimeTryLock(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
testLock.testTimeTryLock(Thread.currentThread());
};
}.start();
}
}
這樣就是正確地使用Lock的方法了。
缺點:
- 不適用於分佈式
注:以上內容僅提供參考和交流,請勿用於商業用途,如有侵權聯繫本人刪除!
持續更新中…
如有對思路不清晰或有更好的解決思路,歡迎與本人交流,QQ羣:273557553,個人微信:
你遇到的問題是小編創作靈感的來源!