為什么調用線程的join方法,等待的是執行join方法的線程


源碼分析:

    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

 

 我們看到,在join方法中,當前執行線程會循環校驗被調用線程對象的isAlive方法來確認被調用線程是否執行完任務,如果沒有,則會調用使線程阻塞的wait方法。

分析wait方法源碼:wait方法是被native修飾的,說明直接使用其他語言與操作系統交互,停止當前線程,也就是當前正在調用join方法執行的線程。

 

 如果代碼如圖:

 

 主線程是執行線程,將被阻塞。

在測試下:

public void testNotify() throws  InterruptedException{
        //        創建任務隊列
        List<ThreadTask> taskList = new ArrayList<>();
        ThreadTask task = new ThreadTask(-1);
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread t2 = Thread.currentThread();
                try {
                    System.out.println("當前線程" + t2.getName());
                    t2.join();// 主線程調用線程t的join方法,被阻塞的是主線程
                } catch (InterruptedException e) {
                }
                System.out.println("當前線程" + t2.getName() + "任務結束");

            }
        });
        t1.start();
        t1.join();
        System.out.println("T1結束");
        t2.start();
        t2.join();
        System.out.println("主線程");
        task.notifyAll();
    }

執行結果:

 

 程序進入了鎖死狀態。t2線程中執行了t2.join使得t2線程進入阻塞狀態,也就是t2線程永遠不肯能結束,而在主線程又調用了t2.join,主線程也鎖死。

 

 

 


免責聲明!

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



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