Lock鎖方式解決線程安全問題

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();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章