在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java/ Java多線程中關(guān)于join的問題?

Java多線程中關(guān)于join的問題?

代碼一:

public static void main(String[] args) throws Exception {
    Thread thread = new Thread(() -> {
      try {
        TimeUnit.SECONDS.sleep(10);
        System.out.println("thread-0 thread exit.");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }, "thread-0");
    thread.start();
    thread.join();
    System.out.println("main thread exit.");
  }

控制臺(10s后打印并退出):

thread-0 thread exit.
main thread exit.

Process finished with exit code 0

代碼二:

public static void main(String[] args) throws Exception {
    Thread.currentThread().join();
    System.out.println("main thread exit.");
  }

控制臺(一直等待中):


問題:第一段代碼是main線程阻塞在thread-0線程上,當(dāng)thread-0執(zhí)行完畢,main線程也同時退出,那第二段代碼中main線程阻塞在哪個線程上呢,為什么沒有退出?

回答
編輯回答
厭惡我

探究

public static void main(String[] args) throws Exception {
    Thread.currentThread().join();
    System.out.println("main thread exit.");
  }

為了了解問題本質(zhì),我們跟進(jìn)去代碼看看,線程的join方法如下:

public final void join() throws InterruptedException {
        join(0);
    }

再繼續(xù)跟:

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;
            }
        }
    }

根據(jù)代碼,其實(shí)join方法最終是待用了wait(0);這行代碼,而wait方法是本地方法.

根據(jù)wait的方法定義,有以下幾點(diǎn)逐一說明:

  • wait()方法在Object類定義,調(diào)用時會獲取該對象上的監(jiān)視器,因此必須在同步代碼塊上調(diào)用.從代碼來看`public final synchronized void join(long millis)
    throws InterruptedException`,因此調(diào)用wait方法后,實(shí)際上是獲取了當(dāng)前對象(根據(jù)調(diào)試查看到是main線程)的監(jiān)視器.
  • 根據(jù)wait方法的定義,它只在在如下幾種情況才會被喚醒,否則將一直等待:
<ul>
  
<li>Some other thread invokes the {@code notify} method for this
      object and thread <var>T</var> happens to be arbitrarily chosen as
      the thread to be awakened.
     
<li>Some other thread invokes the {@code notifyAll} method for this
      object.
      
<li>Some other thread {@linkplain Thread#interrupt() interrupts}
      thread <var>T</var>.
      
<li>The specified amount of real time has elapsed, more or less.  If
      {@code timeout} is zero, however, then real time is not taken into
      consideration and the thread simply waits until notified.
</ul>

總結(jié)

因此,回答你的問題就是,join方法實(shí)質(zhì)是調(diào)用了wait方法.wait方法調(diào)用后阻塞(我不認(rèn)為這是阻塞)在當(dāng)前線程(main線程上),根據(jù)wait的定義,不調(diào)用notify,notifyAll,interrupt以及超時機(jī)制(本例調(diào)用的是wait(0),故不存在這種情況),那么線程將一直處于等待狀態(tài),故一直不會退出。

2018年5月27日 14:59
編輯回答
六扇門

main線程阻塞自己

2017年2月19日 16:18
編輯回答
好難瘦

大致的說下吧,Thread中,join()方法的作用是調(diào)用線程等待該線程完成后,才能繼續(xù)用下運(yùn)行。

public static void main(String[] args) throws InterruptedException
    {
        System.out.println("main start");

        Thread t1 = new Thread(new Worker("thread-1"));
        t1.start();
        t1.join();
        System.out.println("main end");
    }

在上面的例子中,main線程要等到t1線程運(yùn)行結(jié)束后,才會輸出“main end”。如果不加t1.join(),main線程和t1線程是并行的。而加上t1.join(),程序就變成是順序執(zhí)行了。

我們在用到j(luò)oin()的時候,通常都是main線程等到其他多個線程執(zhí)行完畢后再繼續(xù)執(zhí)行。其他多個線程之間并不需要互相等待。

下面這段代碼并沒有實(shí)現(xiàn)讓其他線程并發(fā)執(zhí)行,線程是順序執(zhí)行的。

public static void main(String[] args) throws InterruptedException
    {
        System.out.println("main start");

        Thread t1 = new Thread(new Worker("thread-1"));
        Thread t2 = new Thread(new Worker("thread-2"));
        t1.start();
        //等待t1結(jié)束,這時候t2線程并未啟動
        t1.join();
        
        //t1結(jié)束后,啟動t2線程
        t2.start();
        //等待t2結(jié)束
        t2.join();

        System.out.println("main end");
    }

所以就會是這個結(jié)果

2018年5月19日 11:01