Lock鎖方式解決線程安全問題
源出處:http://www.gulixueyuan.com/my/course/310
Lock(鎖)
-
從JDK 5.0開始,Java提供了更強大的線程同步機制——通過顯式定義同 步鎖對象來實現同步。同步鎖使用Lock對象充當。
-
java.util.concurrent.locks.Lock接口是控制多個線程對共享資源進行訪問的 工具。鎖提供了對共享資源的獨佔訪問,每次只能有一個線程對Lock對象 加鎖,線程開始訪問共享資源之前應先獲得Lock對象。
-
ReentrantLock 類實現了 Lock ,它擁有與 synchronized 相同的併發性和 內存語義,在實現線程安全的控制中,比較常用的是ReentrantLock,可以 顯式加鎖、釋放鎖。
Demo:
class A{
private final ReentrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
//保證線程安全的代碼;
} finally{
lock.unlock();
}
}
}
注意:如果同步代碼有異常,要將unlock()寫入finally語句塊
synchronized 與 Lock 的對比
Lock是顯式鎖(手動開啓和關閉鎖,別忘記關閉鎖),synchronized是 隱式鎖,出了作用域自動釋放
Lock只有代碼塊鎖,synchronized有代碼塊鎖和方法鎖
使用Lock鎖,JVM將花費較少的時間來調度線程,性能更好。並且具有 更好的擴展性(提供更多的子類)
優先使用順序: Lock → 同步代碼塊(已經進入了方法體,分配了相應資源) → 同步方法 (在方法體之外)
————————————————
版權聲明:本文爲CSDN博主「規則固態長方體物質空間移動工程師」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_40164190/article/details/106124756
解決線程安全問題的方式三:Lock鎖
方式一、二請打開:https://blog.csdn.net/qq_40164190/article/details/106119926
class Window implements Runnable{
private int ticket = 100; //100張票
//1.實例化reentrantlock
private ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (true){
try {
//2.調用鎖定的方法lock()
lock.lock();
if (ticket>0){
/* try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
System.out.println(Thread.currentThread().getName()+": 售票,票號爲:"+ticket);
ticket--;
}else{
break;
}
}finally {
//3.調用解鎖的方法:unlock()
lock.unlock();
}
}
}
}
public class LockTest {
public static void main(String[] args) {
Window window = new Window();
Thread thread1 = new Thread(window);
Thread thread2 = new Thread(window);
Thread thread3 = new Thread(window);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}