<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 一.簡介 join()是Thread類的一個方法,根據jdk文檔的定義,join()方法的作用,是等待這個線程結束,即當前線程等待另一個調用join()方法的線程執行結束后再往下執行。通常用于在main主線程內,等待其它調用join()方法的線程執行結束再繼續執行main主線程。 ~~~java /** * Waits for this thread to die. * */ public final void join() throws InterruptedException ~~~ # 二.使用示例 通過下面兩個例子,我們來看看使用join()方法的作用是什么。 ## 1.不使用join()方法的情況 ~~~java public class CreateThreadTest { public static void main(String[] args) { System.out.println("主線程執行開始"); Thread threadA = new Thread(new RunnableTest(), "線程A"); threadA.start(); System.out.println("主線程執行結束"); } } class RunnableTest implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName() + "執行開始"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "執行結束"); } } ~~~ 執行結果如下: ~~~java 主線程執行開始 線程A執行開始 主線程執行結束 線程A執行結束 ~~~ 因為上述子線程執行時間相對較長,所以主線程執行結束之后子線程才執行結束。 ## 2.使用了join()方法的情況 ~~~java public class CreateThreadTest { public static void main(String[] args) { System.out.println("主線程執行開始"); Thread threadA = new Thread(new RunnableTest(), "線程A"); threadA.start(); try { threadA.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主線程執行結束"); } } class RunnableTest implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName() + "執行開始"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "執行結束"); } } ~~~ 執行結果如下: ~~~java 主線程執行開始 線程A執行開始 線程A執行結束 主線程執行結束 ~~~ 對子線程threadA調用了join()方法之后,我們發現主線程會等待子線程執行結束之后才繼續往下執行。 # 三.join()方法的實現原理 下面通過Thread類源碼(JDK1.8)來深入了解一下join()方法: ~~~java public final void join() throws InterruptedException { join(0); } 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; } } } ~~~ 上述代碼,有兩個代碼需要注意下,其一: ~~~java public final synchronized void join(long millis) throws InterruptedException {} ~~~ 成員方法加了synchronized說明是synchronized(this),this是誰?this就是threadA子線程對象本身。也就是說,主線程持有了threadA這個子線程對象的鎖。 其二: ~~~java while (isAlive()) { wait(0); } ~~~ 注意,這個wait()方法是Object類中的方法,也就是說執行wait()方法之后主線 程會釋放threadA對象的鎖,進入等待狀態,直到被再次喚醒。 大家都知道,有了wait(),必然有notify(),什么時候才會notify呢?在jvm源碼里: ~~~java //一個c++函數: void JavaThread::exit(bool destroy_vm, ExitType exit_type) ; //里面有一個賊不起眼的一行代碼 ensure_join(this); static void ensure_join(JavaThread* thread) { Handle threadObj(thread, thread->threadObj()); ObjectLocker lock(threadObj, thread); thread->clear_pending_exception(); java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); java_lang_Thread::set_thread(threadObj(), NULL); //同志們看到了沒,別的不用看,就看這一句 //thread就是當前線程,是啥?就是剛才例子中說的threadA線程 lock.notify_all(thread); thread->clear_pending_exception(); } ~~~ 當子線程threadA執行結束的時候,jvm會自動喚醒阻塞在threadA對象上的線程,在我們的例子中也就是主線程。至此,threadA線程對象被notifyall了,那么主線程也就能繼續跑下去了。 # 四.總結 在main主線程中調用threadA.join()方法,因為join() 方法是一個synchronized方法,所以**主線程會首先持有thread線程對象的鎖**。接下來在join()方法里面調用wait()方法,**主線程會釋放thread線程對象的鎖,進入等待狀態**。最后,threadA線程執行結束,JVM會調用**lock.notify\_all(thread);**喚醒持有threadA這個對象鎖的線程,也就是主線程,所以**主線程會繼續往下執行**。 * * * 參考: [【Java】Thread類中的join()方法原理 ](https://links.jianshu.com/go?to=https%3A%2F%2Fblog.csdn.net%2Fu010983881%2Farticle%2Fdetails%2F80257703)[Java中Thread類的join方法到底是如何實現等待的?](https://links.jianshu.com/go?to=https%3A%2F%2Fwww.zhihu.com%2Fquestion%2F44621343)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看