<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專注安卓開發(fā)

      導(dǎo)航

      join的簡單總結(jié)

      BAT面試題:現(xiàn)在有T1、T2、T3三個線程,你怎樣保證T2在T1執(zhí)行完后執(zhí)行,T3在T2執(zhí)行完后執(zhí)行?

      這個線程問題通常會在第一輪或電話面試階段被問到,目的是檢測你對”join”方法是否熟悉。這個多線程問題比較簡單,可以用join方法實(shí)現(xiàn)。

       

      一、作用

      Thread類中的join方法的主要作用就是同步,它可以使得線程之間的并行執(zhí)行變?yōu)榇袌?zhí)行。具體看代碼:

       1 public class JoinTest {
       2     public static void main(String [] args) throws InterruptedException {
       3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
       4         ThreadJoinTest t2 = new ThreadJoinTest("小東");
       5         t1.start();
       6         /**join的意思是使得放棄當(dāng)前線程的執(zhí)行,并返回對應(yīng)的線程,例如下面代碼的意思就是:
       7          程序在main線程中調(diào)用t1線程的join方法,則main線程放棄cpu控制權(quán),并返回t1線程繼續(xù)執(zhí)行直到線程t1執(zhí)行完畢
       8          所以結(jié)果是t1線程執(zhí)行完后,才到主線程執(zhí)行,相當(dāng)于在main線程中同步t1線程,t1執(zhí)行完了,main線程才有執(zhí)行的機(jī)會
       9          */
      10         t1.join();
      11         t2.start();
      12     }
      13 
      14 }
      15 class ThreadJoinTest extends Thread{
      16     public ThreadJoinTest(String name){
      17         super(name);
      18     }
      19     @Override
      20     public void run(){
      21         for(int i=0;i<1000;i++){
      22             System.out.println(this.getName() + ":" + i);
      23         }
      24     }
      25 }

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

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

       1 public class JoinTest {
       2     public static void main(String [] args) throws InterruptedException {
       3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
       4         ThreadJoinTest t2 = new ThreadJoinTest("小東");
       5         t1.start();
       6         /**join方法可以傳遞參數(shù),join(10)表示main線程會等待t1線程10毫秒,10毫秒過去后,
       7          * main線程和t1線程之間執(zhí)行順序由串行執(zhí)行變?yōu)槠胀ǖ牟⑿袌?zhí)行
       8          */
       9         t1.join(10);
      10         t2.start();
      11     }
      12 
      13 }
      14 class ThreadJoinTest extends Thread{
      15     public ThreadJoinTest(String name){
      16         super(name);
      17     }
      18     @Override
      19     public void run(){
      20         for(int i=0;i<1000;i++){
      21             System.out.println(this.getName() + ":" + i);
      22         }
      23     }
      24 }

      上面代碼結(jié)果是:程序執(zhí)行前面10毫秒內(nèi)打印的都是小明線程,10毫秒后,小明和小東程序交替打印。

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

       

      二、join與start調(diào)用順序問題

      上面的討論大概知道了join的作用了,那么,如果 join在start前調(diào)用,會出現(xiàn)什么后果呢?先看下面的測試結(jié)果

       1 public class JoinTest {
       2     public static void main(String [] args) throws InterruptedException {
       3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
       4         ThreadJoinTest t2 = new ThreadJoinTest("小東");
       5         /**join方法可以在start方法前調(diào)用時,并不能起到同步的作用
       6          */
       7         t1.join();
       8         t1.start();
       9         //Thread.yield();
      10         t2.start();
      11     }
      12 
      13 }
      14 class ThreadJoinTest extends Thread{
      15     public ThreadJoinTest(String name){
      16         super(name);
      17     }
      18     @Override
      19     public void run(){
      20         for(int i=0;i<1000;i++){
      21             System.out.println(this.getName() + ":" + i);
      22         }
      23     }
      24 }

      上面代碼執(zhí)行結(jié)果是:小明和小東線程交替打印。

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

       

      三、join方法實(shí)現(xiàn)原理

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

      其實(shí),join方法是通過調(diào)用線程的wait方法來達(dá)到同步的目的的。例如,A線程中調(diào)用了B線程的join方法,則相當(dāng)于A線程調(diào)用了B線程的wait方法,在調(diào)用了B線程的wait方法后,A線程就會進(jìn)入阻塞狀態(tài),具體看下面的源碼:

       1 public final synchronized void join(long millis)
       2     throws InterruptedException {
       3         long base = System.currentTimeMillis();
       4         long now = 0;
       5 
       6         if (millis < 0) {
       7             throw new IllegalArgumentException("timeout value is negative");
       8         }
       9 
      10         if (millis == 0) {
      11             while (isAlive()) {
      12                 wait(0);
      13             }
      14         } else {
      15             while (isAlive()) {
      16                 long delay = millis - now;
      17                 if (delay <= 0) {
      18                     break;
      19                 }
      20                 wait(delay);
      21                 now = System.currentTimeMillis() - base;
      22             }
      23         }
      24     }

      從源碼中可以看到:join方法的原理就是調(diào)用相應(yīng)線程的wait方法進(jìn)行等待操作的,例如A線程中調(diào)用了B線程的join方法,則相當(dāng)于在A線程中調(diào)用了B線程的wait方法,當(dāng)B線程執(zhí)行完(或者到達(dá)等待時間),B線程會自動調(diào)用自身的notifyAll方法喚醒A線程,從而達(dá)到同步的目的。

       

      posted on 2018-08-17 20:10  安卓筆記俠  閱讀(714)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲精品日韩在线丰满| 亚洲乱理伦片在线观看中字| 国产精品亚洲中文字幕| 国产精品人妻中文字幕| av大片| 国产午夜福利在线视频| 精品天堂色吊丝一区二区| 起碰免费公开97在线视频| 国产高清在线不卡一区| 精品国产综合一区二区三区 | 欧美私人情侣网站| 国产成人一区二区不卡| 少妇尿尿一区二区在线免费| 中文字幕理伦午夜福利片| 亚洲日韩日本中文在线| 老熟女重囗味hdxx69| 好吊视频一区二区三区人妖| 成人午夜在线播放| 福利一区二区在线观看| 亚洲欧美另类久久久精品播放的| 无码天堂亚洲国产AV| 精品国产av一区二区三区| 中文字幕丰满伦子无码ab| 东京热一精品无码av| 精品一区二区三区东京热| 最新国产精品拍自在线观看| 中文文精品字幕一区二区| 亚洲精品成人片在线观看精品字幕 | 国产在线观看免费人成视频| 资溪县| 无码人妻一区二区三区AV| 国产成人午夜福利院| 成年女人午夜毛片免费视频| 蜜臀av一区二区三区在线| 国产精品三级中文字幕| 野花社区www高清视频| 中文字幕一区二区人妻电影| 亚洲精品日韩中文字幕| 丰满爆乳一区二区三区| 亚洲国产成人不卡高清麻豆| 久爱www人成免费网站|