多線程的waitset詳細介紹


代碼演示

package com.dwz.concurrency2.chapter2;

import java.util.stream.IntStream;
/**
 * 1.所有的對象都會有一個wait set,用來存放調用了該對象wait方法之后進入block狀態的線程
 * 2.線程被notify之后,不一定立即得到執行
 * 3.線程從wait set中被喚醒的順序不一定是FIFO
 * 4.線程被喚醒后,必須重新去獲取鎖,會記錄之前wait的位置,在wait的位置繼續往下執行
 */
public class WaitSet {
    private static final Object LOCK = new Object();
    
    private static void work() {
        synchronized (LOCK) {
            System.out.println("begin...");
            
            try {
                System.out.println("Thread will come in.");
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread will out.");
        }
    }
}

測試一:驗證線程從wait set中被喚醒的順序不一定是FIFO

    IntStream.rangeClosed(1, 10).forEach(i-> 
            new Thread(String.valueOf(i)) {
                @Override
                public void run() {
                    synchronized (LOCK) {
                        try {
                            System.out.println(Thread.currentThread().getName() + " will come to wait set.");
                            LOCK.wait();
                            System.err.println(Thread.currentThread().getName() + " will leave to wait set.");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start()
        );
        
        Thread.sleep(3000);
        
        IntStream.rangeClosed(1, 10).forEach(i-> 
            {
                synchronized (LOCK) {
                    LOCK.notify();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        );

測試二:驗證線程被喚醒后,必須重新去獲取鎖,會記錄之前wait的位置,在wait的位置繼續往下執行

     new Thread() {
            @Override
            public void run() {
                work();
            }
        }.start();
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        synchronized (LOCK) {
            LOCK.notifyAll();
        }

注意:線程不能進行自我喚醒,必須由其它線程喚醒


免責聲明!

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



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