<dl id="opymh"></dl>

<div id="opymh"></div>
      <div id="opymh"><tr id="opymh"></tr></div>

        <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

        <em id="opymh"></em>

        <em id="opymh"><ol id="opymh"></ol></em>

              頻道欄目
              首頁 > 程序開發 > 軟件開發 > Java > 正文
              java線程方法之join簡單總結(代碼實例)
              2018-07-27 14:46:17         來源:hkr1363235285的博客  
              收藏   我要投稿

              java線程方法之join簡單總結(代碼實例)

              雖然關于討論線程join方法的博客已經很多了,不過個人感覺挺多都討論得不夠全面,所以我覺得有必要對其進行一個全面的總結。

                一、作用

                Thread類中的join方法的主要作用就是同步,它可以使得線程之間的并行執行變為串行執行。具體看代碼:

              public class JoinTest {
               public static void main(String [] args) throws InterruptedException {
                ThreadJoinTest t1 = new ThreadJoinTest("小明");
                ThreadJoinTest t2 = new ThreadJoinTest("小東");
                t1.start();
                /**join的意思是使得放棄當前線程的執行,并返回對應的線程,例如下面代碼的意思就是:
              程序在main線程中調用t1線程的join方法,則main線程放棄cpu控制權,并返回t1線程繼續執行直到線程t1執行完畢
              所以結果是t1線程執行完后,才到主線程執行,相當于在main線程中同步t1線程,t1執行完了,main線程才有執行的機會
              */
                t1.join();
                t2.start();
               }
              
              }
              class ThreadJoinTest extends Thread{
               public ThreadJoinTest(String name){
                super(name);
               }
               @Override
               public void run(){
                for(int i=0;i<1000;i++){
              System.out.println(this.getName() + ":" + i);
                }
               }
              }

              上面程序結果是先打印完小明線程,在打印小東線程;  

              上面注釋也大概說明了join方法的作用:在A線程中調用了B線程的join()方法時,表示只有當B線程執行完畢時,A線程才能繼續執行。注意,這里調用的join方法是沒有傳參的,join方法其實也可以傳遞一個參數給它的,具體看下面的簡單例子:

              public class JoinTest {
               public static void main(String [] args) throws InterruptedException {
                ThreadJoinTest t1 = new ThreadJoinTest("小明");
                ThreadJoinTest t2 = new ThreadJoinTest("小東");
                t1.start();
                /**join方法可以傳遞參數,join(10)表示main線程會等待t1線程10毫秒,10毫秒過去后,
              * main線程和t1線程之間執行順序由串行執行變為普通的并行執行
              */
                t1.join(10);
                t2.start();
               }
              
              }
              class ThreadJoinTest extends Thread{
               public ThreadJoinTest(String name){
                super(name);
               }
               @Override
               public void run(){
                for(int i=0;i<1000;i++){
              System.out.println(this.getName() + ":" + i);
                }
               }
              }

              上面代碼結果是:程序執行前面10毫秒內打印的都是小明線程,10毫秒后,小明和小東程序交替打印。

              所以,join方法中如果傳入參數,則表示這樣的意思:如果A線程中掉用B線程的join(10),則表示A線程會等待B線程執行10毫秒,10毫秒過后,A、B線程并行執行。需要注意的是,jdk規定,join(0)的意思不是A線程等待B線程0秒,而是A線程等待B線程無限時間,直到B線程執行完畢,即join(0)等價于join()。

                

                二、join與start調用順序問題

                上面的討論大概知道了join的作用了,那么,入股 join在start前調用,會出現什么后果呢?先看下面的測試結果

              public class JoinTest {
               public static void main(String [] args) throws InterruptedException {
                ThreadJoinTest t1 = new ThreadJoinTest("小明");
                ThreadJoinTest t2 = new ThreadJoinTest("小東");
                /**join方法可以在start方法前調用時,并不能起到同步的作用
              */
                t1.join();
                t1.start();
                //Thread.yield();
                t2.start();
               }
              
              }
              class ThreadJoinTest extends Thread{
               public ThreadJoinTest(String name){
                super(name);
               }
               @Override
               public void run(){
                for(int i=0;i<1000;i++){
              System.out.println(this.getName() + ":" + i);
                }
               }
              }

              上面代碼執行結果是:小明和小東線程交替打印。

              所以得到以下結論:join方法必須在線程start方法調用之后調用才有意義。這個也很容易理解:如果一個線程都沒有start,那它也就無法同步了。

                三、join方法實現原理

                有了上面的例子,我們大概知道join方法的作用了,那么,join方法實現的原理是什么呢?

                其實,join方法是通過調用線程的wait方法來達到同步的目的的。例如,A線程中調用了B線程的join方法,則相當于A線程調用了B線程的wait方法,在調用了B線程的wait方法后,A線程就會進入阻塞狀態,具體看下面的源碼

              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方法的原理就是調用相應線程的wait方法進行等待操作的,例如A線程中調用了B線程的join方法,則相當于在A線程中調用了B線程的wait方法,當B線程執行完(或者到達等待時間),B線程會自動調用自身的notifyAll方法喚醒A線程,從而達到同步的目的。

              點擊復制鏈接 與好友分享!回本站首頁
              上一篇:java線程之間的通信方式實例講解
              下一篇:設計模式學習之工廠模式實例解析
              相關文章
              圖文推薦
              點擊排行

              關于我們 | 聯系我們 | 廣告服務 | 投資合作 | 版權申明 | 在線幫助 | 網站地圖 | 作品發布 | Vip技術培訓 | 舉報中心

              版權所有: 紅黑聯盟--致力于做實用的IT技術學習網站

              极速飞艇好假
              <dl id="opymh"></dl>

              <div id="opymh"></div>
                  <div id="opymh"><tr id="opymh"></tr></div>

                    <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                    <em id="opymh"></em>

                    <em id="opymh"><ol id="opymh"></ol></em>

                          <dl id="opymh"></dl>

                          <div id="opymh"></div>
                              <div id="opymh"><tr id="opymh"></tr></div>

                                <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                                <em id="opymh"></em>

                                <em id="opymh"><ol id="opymh"></ol></em>