一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - 關于多線程常用方法以及對鎖的控制(詳解)

關于多線程常用方法以及對鎖的控制(詳解)

2020-10-22 17:35jingxian Java教程

下面小編就為大家帶來一篇關于多線程常用方法以及對鎖的控制(詳解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.sleep()

使當前線程(即調用該方法的線程)暫停執行一段時間,讓其他線程有機會繼續執行,但它并不釋放對象。也就是如果有Synchronized同步塊,其他線程仍然不同訪問共享數據。注意該方法要捕獲異常

比如有兩個線程同時執行(沒有Synchronized),一個線程優先級為MAX_PRIORITY,另一個為MIN_PRIORITY,如果沒有Sleep()方法,只有高優先級的線程執行完成后,低優先級的線程才能執行;但當高優先級的線程sleep(5000)后,低優先級就有機會執行了。

總之,sleep()可以使低優先級的線程得到執行的機會,當然也可以讓同優先級、高優先級的線程有執行的機會。

2.join()

join()方法使調用該方法的線程在此之前執行完畢,也就是等待調用該方法的線程執行完畢后再往下繼續執行。注意該方法也要捕獲異常。

3.yield()

它與sleep()類似,只是不能由用戶指定暫停多長時間,并且yield()方法只能讓同優先級的線程有執行的機會。

4.wait()和notify()、notifyAll()

這三個方法用于協調多個線程對共享數據的存取,所以必須在Synchronized語句塊內使用這三個方法。前面說過Synchronized這個關鍵字用于保護共享數據,阻止其他線程對共享數據的存取。但是這樣程序的流程就很不靈活了,如何才能在當前線程還沒退出Synchronized數據塊時讓其他線程也有機會訪問共享數據呢?此時就用這三個方法來靈活控制。

wait()方法使當前線程暫停執行并釋放對象鎖標志,讓其他線程可以進入Synchronized數據塊,當前線程被放入對象等待池中。當調用 notify()方法后,將從對象的等待池中移走一個任意的線程并放到鎖標志等待池中,只有鎖標志等待池中的線程能夠獲取鎖標志;如果鎖標志等待池中沒有線程,則notify()不起作用。

notifyAll()則從對象等待池中移走所有等待那個對象的線程并放到鎖標志等待池中。

注意 這三個方法都是java.lang.Ojbect的方法!

2.run()和start()

這兩個方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由Java的內存機制規定的。并且run()方法必須是public訪問權限,返回值類型為void。

3.關鍵字Synchronized

這個關鍵字用于保護共享數據,當然前提是要分清哪些數據是共享數據。每個對象都有一個鎖標志,當一個線程訪問該對象時,被Synchronized修飾的數據將被“上鎖”,阻止其他線程訪問。當前線程訪問完這部分數據后釋放鎖標志,其他線程就可以訪問了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public ThreadTest implements Runnable{
  public synchronized void run(){
    for(int i=0;i<10;i++){
      System.out.println(" " + i);
    }
  }
  public static void main(String[] args) {
    Runnable r1 = new ThreadTest();
    Runnable r2 = new ThreadTest();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);
    t1.start();
    t2.start();
  }
}
 
  //以上這段程序中的 i 變量并不是共享數據,也就是這里的Synchronized關鍵字并未起作用。因為t1,t2兩個線程是兩個對象(r1,r2)的線程。//不同的對象其數據是不同的,所以r1和r2兩個對象的i變量是并不是共享數據。
  當把代碼改成如下:Synchronized關鍵字才會起作用
  Runnable r = new ThreadTest();
  Thread t1 = new Thread(r);
  Thread t2 = new Thread(r);
  t1.start();
  t2.start();

wait()和notify(),notifyAll()是Object類的方法,sleep()和yield()是Thread類的方法。

(1).常用的wait方法有wait()和wait(long timeout):

void wait() 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待。

void wait(long timeout) 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量前,導致當前線程等待。

wait()后,線程會釋放掉它所占有的“鎖標志”,從而使線程所在對象中的其它synchronized數據可被別的線程使用。

wait()和notify()因為會對對象的“鎖標志”進行操作,所以它們必須在synchronized函數或synchronized  block中進行調用。如果在non-synchronized函數或non-synchronized block中進行調用,雖然能編譯通過,但在運 行時會發生IllegalMonitorStateException的異常。

(2).Thread.sleep(long millis),必須帶有一個時間參數。

sleep(long)使當前線程進入停滯狀態,所以執行sleep()的線程在指定的時間內肯定不會被執行;

sleep(long)可使優先級低的線程得到執行的機會,當然也可以讓同優先級和高優先級的線程有執行的機會;

sleep(long)是不會釋放鎖標志的。

(3).yield()沒有參數。

sleep 方法使當前運行中的線程睡眼一段時間,進入不可運行狀態,這段時間的長短是由程序設定的,yield 方法使當前線程讓出CPU占有權,但讓出的時間是不可設定的。

yield()也不會釋放鎖標志。

實際上,yield()方法對應了如下操作: 先檢測當前是否有相同優先級的線程處于同可運行狀態,如有,則把 CPU 的占有權交給此線程,否則繼續運行原來的線程。所以yield()方法稱為“退讓”,它把運行機會讓給了同等優先級的其他線程。

sleep方法允許較低優先級的線程獲得運行機會,但yield()方法執行時,當前線程仍處在可運行狀態,所以不可能讓出較低優先級的線程些時獲得CPU占有權。 在一個運行系統中,如果較高優先級的線程沒有調用 sleep 方法,又沒有受到 I/O阻塞,那么較低優先級線程只能等待所有較高優先級的線程運行結束,才有機會運行。

yield()只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態后馬上又被執行。所以yield()只能使同優先級的線程有執行的機會。

以上這篇關于多線程常用方法以及對鎖的控制(詳解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 奇米社区 | 水多多www视频在线观看高清 | 亚洲精品www久久久久久久软件 | 女同志 videos| pron在线观看| 国产中文字幕 | 日韩欧美一卡二区 | 国产手机在线αⅴ片无码观看 | 男人香蕉好大好爽视频 | 新影音先锋男人色资源网 | 成人网欧美亚洲影视图片 | 幻女free性zozo交体内谢 | 99久久综合给久久精品 | 欧美日韩国产一区二区三区伦 | 日韩成人在线免费视频 | 男人与禽交的方法 | 日韩国产成人精品视频人 | 国产精品香蕉夜间视频免费播放 | 日本道三区播放区 | 视频在线视频免费观看 | 色婷亚洲| 日韩一区二区三区在线 | 桥本有菜作品在线 | 国产精品二区高清在线 | 韩国三级hd中文字幕李采潭 | 精品久久久久久午夜 | 门房秦大爷最新章节阅读 | 韩国日本香港毛片免费 | 91热爆在线 | 国产精品怡红院在线观看 | 鞋奴的视频VK | 特黄特黄aaaa级毛片免费看 | 久久不射视频 | 亚洲视频在线免费观看 | 女女宿舍互慰h文小说 | 亚洲国产区中文在线观看 | 四虎影音| sedog在线长片 | 欧美午夜视频一区二区 | 精品视频在线免费观看 | 国产极品美女在线 |