1. 程式人生 > >java 中的sleep()和wait() 的區別

java 中的sleep()和wait() 的區別

1、sleep()

  使當前執行緒(即呼叫該方法的執行緒)暫停執行一段時間,讓其他執行緒有機會繼續執行,但它並不釋放物件鎖。也就是說如果有synchronized同步快,其他執行緒仍然不能訪問共享資料。注意該方法要捕捉異常。 
例如有兩個執行緒同時執行(沒有synchronized)一個執行緒優先順序為MAX_PRIORITY,另一個為MIN_PRIORITY,如果沒有Sleep()方法,只有高優先順序的執行緒執行完畢後,低優先順序的執行緒才能夠執行;但是高優先順序的執行緒sleep(500)後,低優先順序就有機會執行了。

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

2、join()

  join()方法使呼叫該方法的執行緒在此之前執行完畢,也就是等待該方法的執行緒執行完畢後再往下繼續執行。注意該方法也需要捕捉異常。

3、yield()

  該方法與sleep()類似,只是不能由使用者指定暫停多長時間,並且yield()方法只能讓同優先順序的執行緒有執行的機會。

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

  這三個方法用於協調多個執行緒對共享資料的存取,所以必須在synchronized語句塊內使用。synchronized關鍵字用於保護共享資料,阻止其他執行緒對共享資料的存取,但是這樣程式的流程就很不靈活了,如何才能在當前執行緒還沒退出synchronized資料塊時讓其他執行緒也有機會訪問共享資料呢?此時就用這三個方法來靈活控制。 
wait()方法使當前執行緒暫停執行並釋放物件鎖標示,讓其他執行緒可以進入synchronized資料塊,當前執行緒被放入物件等待池中。當呼叫notify()方法後,將從物件的等待池中移走一個任意的執行緒並放到鎖標誌等待池中,只有鎖標誌等待池中執行緒能夠獲取鎖標誌;如果鎖標誌等待池中沒有執行緒,則notify()不起作用。 
notifyAll()則從物件等待池中移走所有等待那個物件的執行緒並放到鎖標誌等待池中。 
注意 這三個方法都是java.lang.Object的方法。

5、run和start()

  把需要處理的程式碼放到run()方法中,start()方法啟動執行緒將自動呼叫run()方法,這個由java的記憶體機制規定的。並且run()方法必需是public訪問許可權,返回值型別為void。

6、關鍵字synchronized

  該關鍵字用於保護共享資料,當然前提條件是要分清哪些資料是共享資料。每個物件都有一個鎖標誌,當一個執行緒訪問到該物件,被Synchronized修飾的資料將被”上鎖”,阻止其他執行緒訪問。當前執行緒訪問完這部分資料後釋放鎖標誌,其他執行緒就可以訪問了。

7、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()方法只能使同優先順序的執行緒有執行的機會。

常用的sleep和wait,synchronized的使用案例程式碼如下:

package com.javathread;


public class ThreadTest {

    public static void main(String[] args) {

        new Thread(new Thread1()).start();

        synchronized (ThreadTest.class) {

            System.out.println("Main Thread go to sleep : currenttime-->"+ System.currentTimeMillis());

            // sleep 過程不會釋放資源
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        System.out.println("Main Thread get up : currenttime-->"+ System.currentTimeMillis());

        new Thread(new Thread2()).start();

        System.out.println("Main Thread over");





    }

    //執行緒一

    static class Thread1 implements Runnable{

        @Override
        public void run() {

            System.out.println("Thread1 is ready: currenttime-->"+System.currentTimeMillis());

            //因為sleep 不會釋放資源,所以在主執行緒sleep結束前,是不能獲取資源鎖的,而是在等待。。

            synchronized (ThreadTest.class) {

                System.out.println("Thread1 is running : currenttime-->"+System.currentTimeMillis());
                System.out.println("Thread1 is wait : currenttime-->"+System.currentTimeMillis());

                try {
                     //呼叫wait()方法,執行緒會放棄物件鎖,進入等待此物件的等待鎖定池
                    ThreadTest.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread1 is over");


            }



        }

    }

    //執行緒二
    static class Thread2 implements Runnable {

        @Override
        public void run() {

            System.out.println("Thread2 is ready :currenttime-->"+ System.currentTimeMillis());

            synchronized (ThreadTest.class) {

                System.out.println("Thread2 is running :currenttime-->"+ System.currentTimeMillis());

                System.out.println("Thread2 notify :currenttime-->"+ System.currentTimeMillis());

                ThreadTest.class.notify();

                System.out.println("Thread2 is over");

            }

        }

    }

}
  • 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
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

執行結果如下:

Main Thread go to sleep : currenttime-->1478616007341
Thread1 is ready: currenttime-->1478616007341
Main Thread get up : currenttime-->1478616012341
Thread1 is running : currenttime-->1478616012341
Thread1 is wait : currenttime-->1478616012341
Main Thread over
Thread2 is ready :currenttime-->1478616012342
Thread2 is running :currenttime-->1478616012342
Thread2 notify :currenttime-->1478616012342
Thread2 is over
Thread1 is over
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

好記性不如爛筆頭。

相關推薦

Javasleep()wait()的區別

對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。 sleep()方法使得程式暫停執行指定的時間,讓出cpu給其他執行緒.在呼叫sleep()方法的過程中,執行緒不會釋放物件鎖,它的監控狀態依然保持著,當指

Javasleep()與wait()區別

學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下:1、每個物件都有一個鎖來控制同步訪問,Synchronized關鍵字可以和物件的鎖互動,來實現同步方法或同步塊。sleep()方法正在執行的執行緒主動讓出CPU(然後CPU就可以去執行其他任務),在slee

Javasleep()與wait()區別標記一下

學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下: 1、每個物件都有一個鎖來控制同步訪問,Synchronized關鍵字可以和物件的鎖互動,來實現同步方法或同步塊。sleep()方法正在執行的執行緒主動讓出CPU(然後CPU就可以去執行其他任務),

多線程sleepwait區別,以及多線程的實現方式及原因,定時器--Timer

守護 驗證 取消 技術 方法 代碼 安全 接口 art 1. Java中sleep和wait的區別 ① 這兩個方法來自不同的類分別是,sleep來自Thread類,和wait來自Object類。 sleep是Thread的靜態類方法,誰調用的誰去睡覺,即使在a線程裏調用b

threadsleepwait方法的區別,以及locksynchronized的區別

最近在專案中設計業務請求邏輯這一塊,運用到了thread的一些知識,所以就又去特定的研究了一下! 首先 sleep和wait的區別: 1、我們通過檢視原始碼得知,sleep是Threa的靜態方法,而wait方法是Object的成員方法; 2、sleep沒有synchnori

Javasleepwait區別

學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下:1、每個物件都有一個鎖來控制同步訪問,Synchronized關鍵字可以和物件的鎖互動,來實現同步方法或同步塊。sleep()方法正在執行的執行緒主動讓出CPU(然後CPU就可以去執行其他任務),在sle

Java Thread sleepwait區別

我們在編寫Java執行緒程式的時候,經常忽略sleep 和 wait方法的區別,導致一些非常棘手的問題,因此瞭解這兩種方法區別有助於我們編寫出更加優質的程式。 區別:                                              sleep()

javaArrayListLinkedList區別

插入 list 新的 查找 arr tro 基於 列表 時間復雜度 ArrayList和LinkedList最主要的區別是基於不同數據結構 ArrayList是基於動態數組的數據結構,LinkedList基於鏈表的數據結構,針對這點,從時間復雜度和空間復雜度來看主要區別:

javaequals==的區別

ML int .net 重寫 com span double str 文獻 (表達可能存在錯誤,需進一步完善) 1、首先搞清楚java裏面的數據類型包括: 基本數據類型和引用數據類型 2、數據類型 基本數據類型: byte,short(2 byte),int(4 byt

JavaArrayListLinkedList區別(轉)

java linked .com -s lan font array href spa 具體詳情參考原博客: http://pengcqu.iteye.com/blog/502676Java中ArrayList和LinkedList區別(轉)

Javaequals==的區別總結

1)對於==,如果作用於基本資料型別的變數,則直接比較其儲存的 “值”是否相等;如果作用於引用型別的變數,則比較的是所指向的物件的地址。 2)對於equals方法,equals方法是Object的,所有繼承了Object類的類都有該方法,注意:equals方法不能作用於基本資料型別的變數

JavaerrorException區別

1、error—錯誤 : 是指程式無法處理的錯誤,表示應用程式執行時出現的重大錯誤。 例如jvm執行時出現的OutOfMemoryError以及Socket程式設計時出現的端口占用等程式無法處理的錯誤 2、Exception — 異常 :異常可分為執行時異常跟編譯異常) 1.執行時異常:

JavainstanceofisInstance區別

instanceof: obj.instanceof(class) 判斷這個物件是不是這種型別, 1.一個物件是本身類的一個物件 2.一個物件是本身類父類(父類的父類)和介面(介面的介面)的一個物件 3.所有物件都是Object 4.凡是null有關的都是fals

JavaComparableComparator區別小結

回到頂部一、Comparable簡介   Comparable是排序介面。若一個類實現了Comparable介面,就意味著該類支援排序。實現了Comparable介面的類的物件的列表或陣列可以通過Collections.sort或Arrays.sort進行自動排序。   此外,實現此介面的物件可以用作有序對映

Android SleepWait區別

1、這兩個方法來自不同的類,sleep來自Thread類,wait 來自Object類。   sleep是Thread的靜態類方法,誰呼叫的誰去睡覺,即使是在a執行緒離呼叫了b的sleep方法,實際上還是a 去睡覺,要讓b去睡覺要在b的程式碼中呼叫sleep. 2、最主要

JavaArrayListLinkedList區別(常見面試題)

一般大家都知道ArrayList和LinkedList的大致區別:     1.ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。     2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為Lin

後端---JavaArrayListLinkedList區別聯絡

ArrayList和LinkedList的區別和聯絡 在一個多月之前,我曾寫過一篇部落格想要迅速簡潔的瞭解Java中所有的集合型別(List、Set、Map),然後一個月多後的我不得已又抱起《Java核心卷I 》仔細研讀,這是為什麼呢??? 是因為“溫故而知新”還是因為“書讀百遍其

JavaArrayListLinkedList區別以及時間複雜度與空間複雜度

Java中ArrayList和LinkedList區別以及時間複雜度與空間複雜度? 一.時間複雜度 二.空間複雜度 三.總結    一般大家都知道ArrayList和LinkedList的大致區別: 1.ArrayList是實現了基於動態陣

多執行緒同步sleepwait區別

1、函式 wait是Object的一個函式,指執行緒處於進入等待狀態,此時執行緒不佔用任何資源,不增加時間限制。wait可以被notify和notifyAll函式喚醒(這兩個也是Object的函

javasleepwait的不同

1,sleep()方法是屬於Thread類中的,wait()方法是屬於Object類中的 2,sleep()方法導致了程式暫停執行指定的時間,讓出cpu,給其他執行緒,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復執行狀態。 3,在呼叫sleep()方法的過程中,執行緒不會釋放物件