国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java使用wait() notify()方法操作共享資源詳解

Java使用wait() notify()方法操作共享資源詳解

2021-01-16 10:57溪山晴雪 Java教程

這篇文章主要為大家詳細介紹了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輸出。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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;
    }
  }
}

測試:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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控制權。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/tashaxing/p/7646215.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产一区二区精品 | 91精品久久久久久久久久 | 国内精品一区二区 | 国产免费一区二区三区 | 免费黄色小片 | 欧美日韩高清一区 | 亚洲欧美精品 | 午夜爽爽 | 欧美成人观看 | 久久久婷婷 | 精品福利一区二区三区 | 丝袜美腿一区二区三区 | 一级全黄少妇性色生活片免费 | 九九九久久国产免费 | 久久久成人精品 | 91精品国产综合久久福利软件 | 日本一区二区三区免费观看 | 久久久久精 | 亚洲欧美日韩国产综合 | 在线观看国产二区 | 日本一区二区视频 | 国产精品亚洲视频 | 国产亚洲精品女人久久久久久 | 日韩免费| 欧美视频精品 | 免费在线毛片 | 国产成人午夜 | 欧美日韩国产一区二区三区不卡 | 日本高清视频在线 | 久久www免费人成看片高清 | 亚洲电影一区二区 | 国产精品极品美女在线观看免费 | 国产一区二区高清在线 | 日韩高清不卡一区二区三区 | 日韩有码一区 | 夜夜草视频 | 一区二区三区在线免费观看 | 龙珠z普通话国语版在线观看 | 久久天天躁狠狠躁夜夜躁2014 | 国产福利电影一区 | 欧美一区二区三区在线 |