日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java wait 释放锁_JAVA锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)...

發布時間:2025/3/12 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java wait 释放锁_JAVA锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

wait是指在一個已經進入了同步鎖的線程內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運行,只有其他線程調用了notify方法(notify并不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手里,別人還沒釋放),調用wait方法的一個或多個線程就會解除wait狀態,重新參與競爭對象鎖,程序如果可以再次得到鎖,就可以繼續向下運行。

1)wait()、notify()和notifyAll()方法是本地方法,并且為final方法,無法被重寫。

2)當前線程必須擁有此對象的monitor(即鎖),才能調用某個對象的wait()方法能讓當前線程阻塞,

(這種阻塞是通過提前釋放synchronized鎖,重新去請求鎖導致的阻塞,這種請求必須有其他線程通過notify()或者notifyAll()喚醒重新競爭獲得鎖)

3)調用某個對象的notify()方法能夠喚醒一個正在等待這個對象的monitor的線程,如果有多個線程都在等待這個對象的monitor,則只能喚醒其中一個線程;

(notify()或者notifyAll()方法并不是真正釋放鎖,必須等到synchronized方法或者語法塊執行完才真正釋放鎖)

4)調用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程,喚醒的線程獲得鎖的概率是隨機的,取決于cpu調度

例子1(錯誤使用導致線程阻塞):三個線程,線程3先擁有sum對象的鎖,然后通過sum.notify()方法通知等待sum鎖的線程去獲得鎖,但是這個時候線程1,2并沒有處于wait()導致的阻塞狀態,而是在synchronized方法塊處阻塞了,所以,這次notify()根本沒有通知到線程1,2。然后線程3正常結束,釋放掉sum鎖,這個時候,線程1就立刻獲得了sum對象的鎖(通過synchronized獲得),然后調用sum.wait()方法釋放掉sum的鎖,線程2隨后獲得了sum對象的線程鎖(通過synchronized獲得),這個時候線程1,2都處于阻塞狀態,但是悲催的是,這之后再也沒有線程主動調用sum.notify()或者notifyAll()方法顯示喚醒這兩個線程,所以程序阻塞

public class CyclicBarrierTest {

public static void main(String[] args) throws Exception {

final Sum sum=new Sum();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread3 get lock");

sum.sum();

sum.notifyAll(); //此時喚醒沒有作用,沒有線程等待

Thread.sleep(2000);

System.out.println("thread3 really release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread1 get lock");

sum.wait();//主動釋放掉sum對象鎖

System.out.println(sum.total);

System.out.println("thread1 release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread2 get lock");

sum.wait(); //釋放sum的對象鎖,等待其他對象喚醒(其他對象釋放sum鎖)

System.out.println(sum.total);

System.out.println("thread2 release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

}

}

class Sum{

public Integer total=0;

public void sum() throws Exception{

total=100;

Thread.sleep(5000);

}

}

thread3 get lock

thread3 really release lock

thread2 get lock

thread1 get lock

//程序后面一直阻塞

例子2:還是上面程序,順序不同,把線程3放到最下面。最后線程1,2都因為沒有再次獲得線程導致線程阻塞

運行過程:

線程1先運行獲得sum對象鎖(通過synchronized),但是隨后執行了sum.wait()方法,主動釋放掉了sum對象鎖,然后線程2獲得了sum對象鎖(通過synchronized),也通過sum.wait()失去sum的對象鎖,最后線程3獲得了sum對象鎖(通過synchronized),主動通過sum.notify()通知了線程1或者2,假設是1,線程1重新通過notify()/notifyAll()的方式獲得了鎖,然后執行完畢,隨后線程釋放鎖,然后這個時候線程2成功獲得鎖,執行完畢。

public class CyclicBarrierTest {

public static void main(String[] args) throws Exception {

final Sum sum=new Sum();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread1 get lock");

sum.wait();//主動釋放sum對象鎖,等待喚醒

System.out.println(sum.total);

System.out.println("thread1 release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread2 get lock");

sum.wait(); //主動釋放sum對象鎖,等待喚醒

System.out.println(sum.total);

System.out.println("thread2 release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

try {

synchronized (sum) {

System.out.println("thread3 get lock");

sum.sum();

sum.notifyAll();//喚醒其他等待線程(線程1,2)

Thread.sleep(2000);

System.out.println("thread3 really release lock");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}).start();

}

}

class Sum{

public Integer total=0;

public void sum() throws Exception{

total=100;

Thread.sleep(5000);

}

}

thread1 get lock

thread2 get lock

thread3 get lock

thread3 really release lock

100

thread2 release lock

100

thread1 release lock

總結

以上是生活随笔為你收集整理的java wait 释放锁_JAVA锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。