Java的Object.wait(long)在等待時間過去后會繼續往后執行嗎


Java的Object.wait(long)在等待時間過去后會繼續往后執行嗎

Object.wait(long)方法相比於wait,多了個等待時長,那么當等待時長過去后,線程會繼續往下執行嗎?

  1. 單個線程執行
  2. 多個線程並發執行
public class ThreadWaitDemo {

    public static final int WAIT_IN_SECONDS = 2;
    public static final int NOTIFY_IN_SECONDS = 6;

    public static void main(String[] args) throws InterruptedException {
        ThreadWaitDemo threadWait = new ThreadWaitDemo();
        Thread a = new Thread(threadWait::justWaitAndPrint, "t1");
        Thread b = new Thread(threadWait::justNotify, "t2");
        a.start();
        //  ① 先注釋這段,讓t1自己執行
        b.start();
    }

    public synchronized void justWaitAndPrint()  {
        try {
            System.out.println(Thread.currentThread().getName() + ": I am in");

            System.out.println(Thread.currentThread().getName() + ": I am gonna wait");
            long start = System.currentTimeMillis();
            wait(WAIT_IN_SECONDS * 1000);
            // 如果時間過了就可以解除等待狀態的話,那么這里的時間間隔就會接近2s
            System.out.println("wait end " + (System.currentTimeMillis() - start) / 1000.0 + "seconds");
        } catch (Exception e) {
            System.out.println(Thread.currentThread().getName() + ": Oops, something bad happen " + e);
        }

        System.out.println(Thread.currentThread().getName() + ": I am out");
    }

    public synchronized void justNotify()  {
        try {
            TimeUnit.SECONDS.sleep(NOTIFY_IN_SECONDS);
            System.out.println(Thread.currentThread().getName() + ": I am in");
        } catch (Exception e) {
            System.out.println(Thread.currentThread().getName() + ": Oops, something bad happen " + e);
        }

        System.out.println(Thread.currentThread().getName() + ": I am out");
    }
}
  • 第一種情況下,運行結果
    t1: I am in
    t1: I am gonna wait
    wait end 2.004seconds
    t1: I am out

  • 第二種情況下,運行結果
    t1: I am in
    t1: I am gonna wait
    t2: I am in
    t2: I am out
    wait end 6.002seconds // 等待時間會隨NOTIFY_IN_SECONDS變化
    t1: I am out

結論:wait(long)在無鎖競爭情況下,在等待時間過去后就直接重新獲取鎖,往后執行;但是在競爭條件下,都會等獲取到鎖了才可以往下執行

附:Java線程狀態

Java的Thread類中定義了一個線程狀態的枚舉,State

      public enum State {
        /**
         * 線程還未啟動
         */
        NEW,

        /**
         * Runnable的線程已經在JVM中執行了,但是可能還在等待OS的一些資源例如處理器
         */
        RUNNABLE,

        /**
         * 線程處於等待一個monitor鎖的狀態
         * 1.等待進入synchronized塊或方法
         * 2.在調用Object.wait后重新進入同步塊
         */
        BLOCKED,

        /**
         * 假設線程A進入waiting狀態,事實上是等待其他的線程B去執行某個特殊的操作
         * 可以讓線程進入waiting狀態的幾種情況:
         * 1.Object#wait()                   等待線程B調用Object.notify()或者Object.notifyAll()
         * 2.B.join()                        等待線程B結束
         * 3.LockSupport.park()              等待線程B調用LockSupport.unpark(A);
         */
        WAITING,

        /**
         * 有時間約束的線程等待狀態
         * 1. Thread.sleep}
         * 2. Object.wait(long)
         * 3. Thread.join(long)
         * 4. LockSupport.parkNanos
         * 5. LockSupport.parkUntil(long deadline)
         */
        TIMED_WAITING,

        /**
         *  終止狀態,線程執行完畢
         */
        TERMINATED;
      }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM