首頁 Java java教程 Java如何使用wait()與notify()方法操作共享資源的實例

Java如何使用wait()與notify()方法操作共享資源的實例

Oct 11, 2017 am 09:52 AM
java notify wait

這篇文章主要為大家詳細介紹了Java使用wait() notify()方法操作共享資源,具有一定的參考價值,有興趣的小伙伴們可以參考一下

Java多個線程共享資源;

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

  2)呼叫某個物件的wait()方法能讓目前執行緒阻塞,且目前執行緒必須擁有此物件的monitor(即鎖,或稱為管程)

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

  4)調用notifyAll()方法能夠喚醒所有正在等待這個物件的monitor的執行緒; 

        在Java中,並以沒有類似PV操作、進程互斥等相關的方法的方法。 JAVA的進程同步是透過synchronized()來實現的,需要說明的是,Java的synchronized()方法類似於作業系統概念中的互斥記憶體區塊,在Java中的Object類別物件中,都是帶有一個內存鎖的,在有線程獲取該內存鎖後,其它線程無法訪問該內存,從而實現Java中簡單的同步、互斥操作。明白這個原理,就能理解為什麼synchronized(this)與synchronized(static XXX)的區別了,synchronized就是針對內存區塊申請內存鎖,this關鍵字代表類的一個對象,所以其內存鎖是針對相同對象的互斥操作,而static成員屬於類別專有,其記憶體空間為該類別所有成員共有,這就導致synchronized()對static成員加鎖,相當於對類別加鎖,也就是在該類別的所有成員間實作互斥,在同一時間只有一個執行緒可存取該類別的實例。如果需要在執行緒間相互喚醒就需要藉助Object類別的wait()方法及nofity()方法。

說了這麼一堆,可能似懂非懂,那麼接下來用一個例子來說明問題,用多線程實現連續的1,2,1,2,1,2,1,2, 1,2輸出。


package com.study.thread;
/**
 * 多线程
 * @ClassName: PrintFile 
 * @date 2017年10月10日 下午4:05:04
 */
public class PrintFile implements Runnable{
  //当前线程id
  private int id ;
  //共享资源
  public byte[] res ;
  
  //如果类里写了有参构造器,而任然想保留无参数构造方法,则必须显式的写出该方法。
  public PrintFile() {
    super();
//    System.out.println("我是构造器"); 
  }

  public PrintFile(int id, byte[] res) {
    //构造器中使用super()/this(),必须放在第一行。
    this(); 
    this.id = id;
    this.res = res;
  }

  //静态计数器
  public static int count = 5;
  
  @Override
  public void run() {
    synchronized (res) {
      while(count-->=0){
        try {
          res.notify();//唤醒其他线程中的某一个(唤醒等待res的其他线程,当前线程执行完后要释放锁)
          System.out.println("当前线程id值:"+id);
          
          res.wait();//当前线程阻塞,等待被唤醒
          System.out.println("现在执行的线程是"+Thread.currentThread().getName()+",--wait()后的代码继续执行:"+id);
          
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      return; 
    }
  }
}
登入後複製

測試:


#
package com.study.thread;

public class PrintFileTest {
 public static void main(String[] args) {
  byte[] res = new byte[]{0,1,2};//共享资源
  PrintFile p1 = new PrintFile(1, res);
  PrintFile p2 = new PrintFile(2, res);
  
  Thread t1 = new Thread(p1, "a");
  Thread t2 = new Thread(p2, "b");
    
  t1.start();
  t2.start();
 }
}
登入後複製

結果:

目前執行緒id值:1
目前執行緒id值:2
現在執行的執行緒是a,--wait()後的程式碼繼續執行:1
目前執行緒id值:1
現在執行的執行緒是b,-- wait()後的程式碼繼續執行:2
目前執行緒id值:2
現在執行的執行緒是a,--wait()後的程式碼繼續執行:1
目前執行緒id值:1
現在執行的執行緒是b,--wait()後的程式碼繼續執行:2
目前執行緒id值:2
現在執行的執行緒是a,--wait()後的程式碼繼續執行:1

下面解釋為什麼會出現這樣的結果:

首先1、2號執行緒啟動,這裡假設1號執行緒先執行run方法取得資源(其實是不確定的),取得物件a的鎖,進入while迴圈(用於控制輸出幾輪):

1、此時物件呼叫它的喚醒方法notify(),意思是這個同步區塊執行完後它要釋放鎖,把鎖交給等待a資源的執行緒;

2、輸出1;

3、該物件執行等待方法,意思是此時此刻起擁有這個物件鎖的執行緒(也就是這裡的1號執行緒)釋放CPU控制權,釋放鎖,且執行緒進入阻塞狀態,後面的程式碼暫時不執行,因未執行完同步區塊,所以1也沒起作用;

# 4.在這之前的某時刻線程2運行run方法,但苦於沒有獲得a對象的鎖,所以無法繼續運行,但3步驟之後,它獲得了a的鎖,此時執行a的喚醒方法notify() ,同理,意思是這個同步區塊執行完後它要釋放鎖,把鎖交給等待a資源的執行緒;

#5、輸出2;

6、執行a的等待方法,意思是此時此刻起擁有這個物件鎖的執行緒(也就是這裡的2號執行緒)釋放CPU控制權,釋放鎖,並且執行緒進入阻塞狀態,後面的程式碼暫時不執行,因未執行完同步區塊,所以2號執行緒的4步驟的喚醒方法也沒起作用;

7、此時1號執行緒執行到3步驟,發現物件鎖定沒有被使用,所以繼續執行3步驟中wait方法後面的程式碼,於是輸出:------執行緒1取得鎖,wait()後的程式碼繼續運作:1;

8、此時while迴圈滿足條件,繼續執行,所以,再執行1號執行緒的喚醒方法,意思是這個同步區塊執行完後它要釋放鎖定;

9、輸出1;

10、執行等待方法,執行緒1阻塞,釋放資源鎖定;

11、此時執行緒2又獲得了鎖,執行到步驟6,繼續執行wait方法後面的程式碼,所以輸出:------執行緒2取得鎖,wait()後的程式碼繼續運作:2;

12、繼續執行while循環,輸出2;

··· ···

透過上述步驟,相信大家已經明白這兩個方法的使用了,但該程式還存在一個問題,當while循環不滿足條件時,肯定會有執行緒還在等待資源,所以主執行緒一直不會終止。當然這個程式的目的只是為了給大家示範這兩個方法怎麼用。

總結:

#

 wait()方法與notify()必須與synchronized(resource)一起使用。也就是wait與notify針對已經取得了resource鎖的執行緒進行操作,從語法角度來說就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句區塊內。從功能上來說wait()執行緒在取得物件鎖後,主動釋放CPU控制權,主動釋放物件鎖,同時本執行緒休眠。直到有其它線程呼叫物件的notify()喚醒該線程,才能繼續取得物件鎖定,並繼續執行。對應的notify()就是對物件鎖的釋放操作。 【因此,我們可以發現,wait和notify方法都可以釋放物件的鎖,但wait同時釋放CPU控制權,即它後面的程式碼停止執行,執行緒進入阻塞狀態,而notify方法不立刻釋放CPU控制權,而是在對應的synchronized(){}語句塊執行結束,再自動釋放鎖定。 】釋放鎖定後,JVM會在等待resoure的線程中選取一線程,賦予其物件鎖定,喚醒線程,繼續執行。這樣就提供了在執行緒間同步、喚醒的操作。 Thread.sleep()與Object.wait()二者都可以暫停當前線程,釋放CPU控制權,主要的區別在於Object.wait()在釋放CPU同時,釋放了物件鎖的控制,而在同步區塊中的Thread.sleep()方法並不會釋放鎖,僅釋放CPU控制權。

以上是Java如何使用wait()與notify()方法操作共享資源的實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1431
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP與Python:核心功能 PHP與Python:核心功能 Apr 13, 2025 am 12:16 AM

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP:許多網站的基礎 PHP:許多網站的基礎 Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP與Python:用例和應用程序 PHP與Python:用例和應用程序 Apr 17, 2025 am 12:23 AM

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。

H5:工具,框架和最佳實踐 H5:工具,框架和最佳實踐 Apr 11, 2025 am 12:11 AM

H5開發需要掌握的工具和框架包括Vue.js、React和Webpack。 1.Vue.js適用於構建用戶界面,支持組件化開發。 2.React通過虛擬DOM優化頁面渲染,適合複雜應用。 3.Webpack用於模塊打包,優化資源加載。

See all articles