1、现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
1 package com.mianshi.easy; 2 class JoinDemo implements Runnable{ 3 public void run() { 4 for(int i=0;i<100;i++){ 5 System.out.println(Thread.currentThread().getName()+"……"+ i); 6 } 7 } 8 } 9 10 public class JoinMethod {11 12 public static void main(String[] args) throws InterruptedException {13 JoinDemo jd = new JoinDemo();14 Thread T1 = new Thread(jd);15 Thread T2 = new Thread(jd);16 Thread T3 = new Thread(jd);17 18 T1.start(); 19 //当t1拿着执行权把这些数据都打印完了,主线程才恢复到运行中来20 T1.join(); 21 22 T2.start();23 T2.join();24 25 T3.start();26 T3.join();27 28 }29 }
结果:
Thread-0……0Thread-0……1Thread-0……2Thread-0……3Thread-0……4Thread-0……5Thread-0……6Thread-0……7Thread-0……8Thread-0……9Thread-0……10Thread-0……11Thread-0……12Thread-0……13Thread-0……14Thread-0……15Thread-0……16Thread-0……17Thread-0……18Thread-0……19Thread-0……20Thread-0……21Thread-0……22Thread-0……23Thread-0……24Thread-0……25Thread-0……26Thread-0……27Thread-0……28Thread-0……29Thread-0……30Thread-0……31Thread-0……32Thread-0……33Thread-0……34Thread-0……35Thread-0……36Thread-0……37Thread-0……38Thread-0……39Thread-0……40Thread-0……41Thread-0……42Thread-0……43Thread-0……44Thread-0……45Thread-0……46Thread-0……47Thread-0……48Thread-0……49Thread-0……50Thread-0……51Thread-0……52Thread-0……53Thread-0……54Thread-0……55Thread-0……56Thread-0……57Thread-0……58Thread-0……59Thread-0……60Thread-0……61Thread-0……62Thread-0……63Thread-0……64Thread-0……65Thread-0……66Thread-0……67Thread-0……68Thread-0……69Thread-0……70Thread-0……71Thread-0……72Thread-0……73Thread-0……74Thread-0……75Thread-0……76Thread-0……77Thread-0……78Thread-0……79Thread-0……80Thread-0……81Thread-0……82Thread-0……83Thread-0……84Thread-0……85Thread-0……86Thread-0……87Thread-0……88Thread-0……89Thread-0……90Thread-0……91Thread-0……92Thread-0……93Thread-0……94Thread-0……95Thread-0……96Thread-0……97Thread-0……98Thread-0……99Thread-1……0Thread-1……1Thread-1……2Thread-1……3Thread-1……4Thread-1……5Thread-1……6Thread-1……7Thread-1……8Thread-1……9Thread-1……10Thread-1……11Thread-1……12Thread-1……13Thread-1……14Thread-1……15Thread-1……16Thread-1……17Thread-1……18Thread-1……19Thread-1……20Thread-1……21Thread-1……22Thread-1……23Thread-1……24Thread-1……25Thread-1……26Thread-1……27Thread-1……28Thread-1……29Thread-1……30Thread-1……31Thread-1……32Thread-1……33Thread-1……34Thread-1……35Thread-1……36Thread-1……37Thread-1……38Thread-1……39Thread-1……40Thread-1……41Thread-1……42Thread-1……43Thread-1……44Thread-1……45Thread-1……46Thread-1……47Thread-1……48Thread-1……49Thread-1……50Thread-1……51Thread-1……52Thread-1……53Thread-1……54Thread-1……55Thread-1……56Thread-1……57Thread-1……58Thread-1……59Thread-1……60Thread-1……61Thread-1……62Thread-1……63Thread-1……64Thread-1……65Thread-1……66Thread-1……67Thread-1……68Thread-1……69Thread-1……70Thread-1……71Thread-1……72Thread-1……73Thread-1……74Thread-1……75Thread-1……76Thread-1……77Thread-1……78Thread-1……79Thread-1……80Thread-1……81Thread-1……82Thread-1……83Thread-1……84Thread-1……85Thread-1……86Thread-1……87Thread-1……88Thread-1……89Thread-1……90Thread-1……91Thread-1……92Thread-1……93Thread-1……94Thread-1……95Thread-1……96Thread-1……97Thread-1……98Thread-1……99Thread-2……0Thread-2……1Thread-2……2Thread-2……3Thread-2……4Thread-2……5Thread-2……6Thread-2……7Thread-2……8Thread-2……9Thread-2……10Thread-2……11Thread-2……12Thread-2……13Thread-2……14Thread-2……15Thread-2……16Thread-2……17Thread-2……18Thread-2……19Thread-2……20Thread-2……21Thread-2……22Thread-2……23Thread-2……24Thread-2……25Thread-2……26Thread-2……27Thread-2……28Thread-2……29Thread-2……30Thread-2……31Thread-2……32Thread-2……33Thread-2……34Thread-2……35Thread-2……36Thread-2……37Thread-2……38Thread-2……39Thread-2……40Thread-2……41Thread-2……42Thread-2……43Thread-2……44Thread-2……45Thread-2……46Thread-2……47Thread-2……48Thread-2……49Thread-2……50Thread-2……51Thread-2……52Thread-2……53Thread-2……54Thread-2……55Thread-2……56Thread-2……57Thread-2……58Thread-2……59Thread-2……60Thread-2……61Thread-2……62Thread-2……63Thread-2……64Thread-2……65Thread-2……66Thread-2……67Thread-2……68Thread-2……69Thread-2……70Thread-2……71Thread-2……72Thread-2……73Thread-2……74Thread-2……75Thread-2……76Thread-2……77Thread-2……78Thread-2……79Thread-2……80Thread-2……81Thread-2……82Thread-2……83Thread-2……84Thread-2……85Thread-2……86Thread-2……87Thread-2……88Thread-2……89Thread-2……90Thread-2……91Thread-2……92Thread-2……93Thread-2……94Thread-2……95Thread-2……96Thread-2……97Thread-2……98Thread-2……99
2、练习demo
(1)主线程向下转时,碰到了t1.join(),t1要申请加入到运行中来,就是要CPU执行权。这时CPU执行权在主线程手里,主线程就把CPU执行权给放开,陷入冻结状态。活着的只有t1了,只有当t1拿着执行权把这些数据都打印完了,主线程才恢复到运行中来。
1 package com.mianshi.easy; 2 3 class JoinDemo implements Runnable{ 4 5 public void run() { 6 for(int i=0;i<100;i++){ 7 System.out.println(Thread.currentThread().getName()+"……"+ i); 8 } 9 }10 }11 12 /**13 * 主线程向下转时,碰到了t1.join(),t1要申请加入到运行中来,就是要CPU执行权。14 * 这时候CPU执行权在主线程手里,主线程就把CPU执行权给放开,陷入冻结状态。活着的15 * 只有t1了,只有当t1拿着执行权把这些数据都打印完了,主线程才恢复到运行中来。16 * */17 public class JoinMethod {18 19 public static void main(String[] args) throws InterruptedException {20 JoinDemo jd = new JoinDemo();21 Thread t1 = new Thread(jd);22 Thread t2 = new Thread(jd);23 24 t1.start();25 26 t1.join(); 27 28 t2.start();29 30 for(int j =0; j<100; j++){31 System.out.println(Thread.currentThread().getName()+"……"+j);32 }33 }34 }
结果:
Thread-0……0Thread-0……1Thread-0……2Thread-0……3Thread-0……4Thread-0……5Thread-0……6Thread-0……7Thread-0……8Thread-0……9Thread-0……10Thread-0……11Thread-0……12Thread-0……13Thread-0……14Thread-0……15Thread-0……16Thread-0……17Thread-0……18Thread-0……19Thread-0……20Thread-0……21Thread-0……22Thread-0……23Thread-0……24Thread-0……25Thread-0……26Thread-0……27Thread-0……28Thread-0……29Thread-0……30Thread-0……31Thread-0……32Thread-0……33Thread-0……34Thread-0……35Thread-0……36Thread-0……37Thread-0……38Thread-0……39Thread-0……40Thread-0……41Thread-0……42Thread-0……43Thread-0……44Thread-0……45Thread-0……46Thread-0……47Thread-0……48Thread-0……49Thread-0……50Thread-0……51Thread-0……52Thread-0……53Thread-0……54Thread-0……55Thread-0……56Thread-0……57Thread-0……58Thread-0……59Thread-0……60Thread-0……61Thread-0……62Thread-0……63Thread-0……64Thread-0……65Thread-0……66Thread-0……67Thread-0……68Thread-0……69Thread-0……70Thread-0……71Thread-0……72Thread-0……73Thread-0……74Thread-0……75Thread-0……76Thread-0……77Thread-0……78Thread-0……79Thread-0……80Thread-0……81Thread-0……82Thread-0……83Thread-0……84Thread-0……85Thread-0……86Thread-0……87Thread-0……88Thread-0……89Thread-0……90Thread-0……91Thread-0……92Thread-0……93Thread-0……94Thread-0……95Thread-0……96Thread-0……97Thread-0……98Thread-0……99main……0main……1main……2main……3main……4main……5main……6main……7main……8main……9main……10main……11main……12main……13main……14main……15main……16main……17main……18main……19main……20main……21main……22main……23main……24main……25main……26main……27main……28main……29main……30main……31main……32main……33main……34main……35Thread-1……0main……36Thread-1……1main……37Thread-1……2main……38Thread-1……3main……39Thread-1……4main……40Thread-1……5main……41Thread-1……6Thread-1……7main……42Thread-1……8main……43Thread-1……9main……44Thread-1……10main……45Thread-1……11Thread-1……12main……46Thread-1……13main……47Thread-1……14main……48Thread-1……15main……49Thread-1……16main……50Thread-1……17main……51Thread-1……18main……52Thread-1……19main……53Thread-1……20Thread-1……21Thread-1……22Thread-1……23Thread-1……24Thread-1……25main……54main……55main……56main……57Thread-1……26main……58Thread-1……27main……59Thread-1……28main……60Thread-1……29main……61Thread-1……30main……62Thread-1……31main……63Thread-1……32main……64Thread-1……33main……65Thread-1……34main……66Thread-1……35main……67Thread-1……36main……68Thread-1……37main……69Thread-1……38main……70Thread-1……39main……71Thread-1……40main……72Thread-1……41main……73Thread-1……42main……74Thread-1……43main……75Thread-1……44main……76Thread-1……45main……77Thread-1……46main……78Thread-1……47main……79Thread-1……48main……80Thread-1……49main……81Thread-1……50main……82Thread-1……51main……83Thread-1……52main……84Thread-1……53main……85Thread-1……54main……86Thread-1……55main……87Thread-1……56main……88Thread-1……57main……89Thread-1……58main……90Thread-1……59main……91Thread-1……60main……92Thread-1……61main……93Thread-1……62main……94Thread-1……63main……95Thread-1……64main……96Thread-1……65main……97Thread-1……66main……98Thread-1……67main……99Thread-1……68Thread-1……69Thread-1……70Thread-1……71Thread-1……72Thread-1……73Thread-1……74Thread-1……75Thread-1……76Thread-1……77Thread-1……78Thread-1……79Thread-1……80Thread-1……81Thread-1……82Thread-1……83Thread-1……84Thread-1……85Thread-1……86Thread-1……87Thread-1……88Thread-1……89Thread-1……90Thread-1……91Thread-1……92Thread-1……93Thread-1……94Thread-1……95Thread-1……96Thread-1……97Thread-1……98Thread-1……99
(2)改变顺序,主线程启动了两个子线程A、B时,其中一个子线程A调用了join()方法后,主线程将释放执行权,进入冻结状态。子线程A并不会影响子线程B,两个子线程将会交替执行,直到A线程run()方法执行完,主线程将会重新获得执行权。
1 package com.mianshi.easy; 2 3 class JoinDemo implements Runnable{ 4 5 public void run() { 6 for(int i=0;i<200;i++){ 7 System.out.println(Thread.currentThread().getName()+"……"+ i); 8 } 9 }10 }11 12 /**13 * 将t1.join()和t2.start()位置互换。主线程开启了t1、t2,这时候CPU执行权还在主线程手里。14 * 当主线程碰到了t1.join(),释放执行权,处于冻结状态。活着的t1、t2都具备执行资格,这时候CPU15 * 便对t1和t2交替执行。主线程要等到t1结束才能活,至于t2结不结束,与主线程没有丝毫关系。如果t116 * 结束了,t2还没结束,主线程就会和t2抢执行权执行。主线程碰到谁的join,它就等谁。也就是说,谁17 * 让它把执行权放出来,它就等谁死。至于谁去抢,它不管。18 * 19 * */20 public class JoinMethod {21 22 public static void main(String[] args) throws InterruptedException {23 JoinDemo jd = new JoinDemo();24 Thread t1 = new Thread(jd);25 Thread t2 = new Thread(jd);26 27 t1.start();28 29 t2.start();30 31 t1.join(); 32 33 for(int j =0; j<100; j++){34 System.out.println(Thread.currentThread().getName()+"……"+j);35 }36 }37 }
结果:
Thread-1……0Thread-0……0Thread-0……1Thread-1……1Thread-0……2Thread-1……2Thread-0……3Thread-1……3Thread-0……4Thread-0……5Thread-0……6Thread-0……7Thread-0……8Thread-0……9Thread-1……4Thread-1……5Thread-1……6Thread-1……7Thread-1……8Thread-1……9Thread-1……10Thread-1……11Thread-1……12Thread-0……10Thread-1……13Thread-1……14Thread-1……15Thread-1……16Thread-1……17Thread-1……18Thread-1……19Thread-1……20Thread-1……21Thread-1……22Thread-1……23Thread-1……24Thread-1……25Thread-1……26Thread-0……11Thread-0……12Thread-0……13Thread-0……14Thread-0……15Thread-0……16Thread-0……17Thread-1……27Thread-0……18Thread-1……28Thread-0……19Thread-1……29Thread-0……20Thread-1……30Thread-0……21Thread-1……31Thread-1……32Thread-1……33Thread-1……34Thread-1……35Thread-1……36Thread-1……37Thread-1……38Thread-1……39Thread-1……40Thread-1……41Thread-1……42Thread-1……43Thread-1……44Thread-1……45Thread-1……46Thread-1……47Thread-0……22Thread-1……48Thread-0……23Thread-1……49Thread-0……24Thread-1……50Thread-0……25Thread-1……51Thread-0……26Thread-1……52Thread-0……27Thread-1……53Thread-0……28Thread-1……54Thread-0……29Thread-1……55Thread-0……30Thread-1……56Thread-0……31Thread-1……57Thread-1……58Thread-1……59Thread-1……60Thread-1……61Thread-1……62Thread-1……63Thread-1……64Thread-1……65Thread-1……66Thread-1……67Thread-1……68Thread-1……69Thread-1……70Thread-1……71Thread-0……32Thread-1……72Thread-0……33Thread-1……73Thread-0……34Thread-1……74Thread-0……35Thread-1……75Thread-0……36Thread-1……76Thread-0……37Thread-1……77Thread-0……38Thread-0……39Thread-0……40Thread-0……41Thread-0……42Thread-0……43Thread-1……78Thread-0……44Thread-1……79Thread-0……45Thread-1……80Thread-0……46Thread-1……81Thread-0……47Thread-1……82Thread-0……48Thread-1……83Thread-0……49Thread-1……84Thread-0……50Thread-1……85Thread-0……51Thread-1……86Thread-0……52Thread-1……87Thread-0……53Thread-1……88Thread-0……54Thread-1……89Thread-0……55Thread-1……90Thread-0……56Thread-1……91Thread-0……57Thread-1……92Thread-0……58Thread-1……93Thread-0……59Thread-1……94Thread-0……60Thread-1……95Thread-0……61Thread-1……96Thread-0……62Thread-1……97Thread-0……63Thread-1……98Thread-0……64Thread-1……99Thread-0……65Thread-1……100Thread-0……66Thread-1……101Thread-0……67Thread-1……102Thread-0……68Thread-1……103Thread-0……69Thread-1……104Thread-0……70Thread-1……105Thread-0……71Thread-1……106Thread-0……72Thread-1……107Thread-0……73Thread-1……108Thread-1……109Thread-0……74Thread-1……110Thread-0……75Thread-1……111Thread-0……76Thread-1……112Thread-0……77Thread-1……113Thread-1……114Thread-0……78Thread-1……115Thread-0……79Thread-1……116Thread-0……80Thread-1……117Thread-0……81Thread-1……118Thread-0……82Thread-1……119Thread-0……83Thread-1……120Thread-0……84Thread-1……121Thread-0……85Thread-1……122Thread-0……86Thread-1……123Thread-0……87Thread-1……124Thread-0……88Thread-1……125Thread-0……89Thread-1……126Thread-0……90Thread-1……127Thread-0……91Thread-1……128Thread-0……92Thread-1……129Thread-0……93Thread-1……130Thread-0……94Thread-1……131Thread-0……95Thread-1……132Thread-0……96Thread-1……133Thread-0……97Thread-1……134Thread-0……98Thread-1……135Thread-0……99Thread-1……136Thread-0……100Thread-1……137Thread-0……101Thread-1……138Thread-0……102Thread-1……139Thread-0……103Thread-1……140Thread-0……104Thread-1……141Thread-0……105Thread-1……142Thread-0……106Thread-1……143Thread-0……107Thread-1……144Thread-0……108Thread-1……145Thread-1……146Thread-1……147Thread-0……109Thread-1……148Thread-0……110Thread-1……149Thread-0……111Thread-1……150Thread-0……112Thread-1……151Thread-0……113Thread-1……152Thread-0……114Thread-1……153Thread-0……115Thread-1……154Thread-0……116Thread-1……155Thread-0……117Thread-1……156Thread-0……118Thread-1……157Thread-0……119Thread-1……158Thread-0……120Thread-1……159Thread-0……121Thread-0……122Thread-1……160Thread-0……123Thread-1……161Thread-0……124Thread-1……162Thread-0……125Thread-0……126Thread-0……127Thread-0……128Thread-0……129Thread-0……130Thread-0……131Thread-0……132Thread-0……133Thread-0……134Thread-0……135Thread-0……136Thread-0……137Thread-0……138Thread-0……139Thread-0……140Thread-0……141Thread-0……142Thread-0……143Thread-0……144Thread-0……145Thread-0……146Thread-0……147Thread-0……148Thread-0……149Thread-0……150Thread-0……151Thread-0……152Thread-0……153Thread-0……154Thread-0……155Thread-0……156Thread-0……157Thread-0……158Thread-0……159Thread-0……160Thread-0……161Thread-0……162Thread-0……163Thread-0……164Thread-0……165Thread-0……166Thread-0……167Thread-0……168Thread-0……169Thread-0……170Thread-0……171Thread-0……172Thread-0……173Thread-0……174Thread-0……175Thread-0……176Thread-0……177Thread-0……178Thread-0……179Thread-0……180Thread-0……181Thread-0……182Thread-0……183Thread-0……184Thread-0……185Thread-0……186Thread-0……187Thread-0……188Thread-0……189Thread-0……190Thread-0……191Thread-0……192Thread-0……193Thread-0……194Thread-0……195Thread-0……196Thread-0……197Thread-0……198Thread-0……199Thread-1……163Thread-1……164main……0main……1main……2main……3main……4main……5main……6main……7main……8main……9main……10main……11main……12main……13main……14main……15main……16main……17main……18main……19main……20main……21main……22main……23main……24main……25main……26main……27main……28main……29main……30main……31main……32main……33main……34main……35main……36main……37main……38main……39main……40main……41main……42main……43main……44main……45main……46main……47main……48main……49main……50main……51main……52main……53main……54main……55main……56main……57main……58main……59Thread-1……165main……60Thread-1……166main……61Thread-1……167main……62main……63main……64main……65main……66main……67main……68main……69main……70main……71main……72main……73main……74main……75main……76Thread-1……168main……77Thread-1……169main……78Thread-1……170main……79Thread-1……171main……80Thread-1……172main……81Thread-1……173main……82Thread-1……174main……83Thread-1……175main……84Thread-1……176main……85Thread-1……177main……86Thread-1……178main……87Thread-1……179main……88Thread-1……180main……89Thread-1……181main……90Thread-1……182main……91Thread-1……183main……92Thread-1……184main……93Thread-1……185main……94Thread-1……186main……95Thread-1……187main……96Thread-1……188main……97Thread-1……189main……98Thread-1……190main……99Thread-1……191Thread-1……192Thread-1……193Thread-1……194Thread-1……195Thread-1……196Thread-1……197Thread-1……198Thread-1……199
顺便贴下java.lang.Thread中关于join()方法的实现代码:
1 /** 2 * Waits at most { @code millis} milliseconds for this thread to 3 * die. A timeout of { @code 0} means to wait forever. 4 * 5 *This implementation uses a loop of {
@code this.wait} calls 6 * conditioned on { @code this.isAlive}. As a thread terminates the 7 * { @code this.notifyAll} method is invoked. It is recommended that 8 * applications not use { @code wait}, { @code notify}, or 9 * { @code notifyAll} on { @code Thread} instances. 10 * 11 * @param millis 12 * the time to wait in milliseconds 13 * 14 * @throws IllegalArgumentException 15 * if the value of { @code millis} is negative 16 * 17 * @throws InterruptedException 18 * if any thread has interrupted the current thread. The 19 * interrupted status of the current thread is 20 * cleared when this exception is thrown. 21 */ 22 public final synchronized void join(long millis) 23 throws InterruptedException { 24 long base = System.currentTimeMillis(); 25 long now = 0; 26 27 if (millis < 0) { 28 throw new IllegalArgumentException("timeout value is negative"); 29 } 30 31 if (millis == 0) { 32 while (isAlive()) { 33 wait(0); 34 } 35 } else { 36 while (isAlive()) { 37 long delay = millis - now; 38 if (delay <= 0) { 39 break; 40 } 41 wait(delay); 42 now = System.currentTimeMillis() - base; 43 } 44 } 45 } 46 47 /** 48 * Waits at most { @code millis} milliseconds plus 49 * { @code nanos} nanoseconds for this thread to die. 50 * 51 *This implementation uses a loop of {
@code this.wait} calls 52 * conditioned on { @code this.isAlive}. As a thread terminates the 53 * { @code this.notifyAll} method is invoked. It is recommended that 54 * applications not use { @code wait}, { @code notify}, or 55 * { @code notifyAll} on { @code Thread} instances. 56 * 57 * @param millis 58 * the time to wait in milliseconds 59 * 60 * @param nanos 61 * { @code 0-999999} additional nanoseconds to wait 62 * 63 * @throws IllegalArgumentException 64 * if the value of { @code millis} is negative, or the value 65 * of { @code nanos} is not in the range { @code 0-999999} 66 * 67 * @throws InterruptedException 68 * if any thread has interrupted the current thread. The 69 * interrupted status of the current thread is 70 * cleared when this exception is thrown. 71 */ 72 public final synchronized void join(long millis, int nanos) 73 throws InterruptedException { 74 75 if (millis < 0) { 76 throw new IllegalArgumentException("timeout value is negative"); 77 } 78 79 if (nanos < 0 || nanos > 999999) { 80 throw new IllegalArgumentException( 81 "nanosecond timeout value out of range"); 82 } 83 84 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 85 millis++; 86 } 87 88 join(millis); 89 } 90 91 /** 92 * Waits for this thread to die. 93 * 94 *An invocation of this method behaves in exactly the same 95 * way as the invocation 96 * 97 *
98 * { @linkplain #join(long) join}{ @code (0)} 99 *100 *101 * @throws InterruptedException102 * if any thread has interrupted the current thread. The103 * interrupted status of the current thread is104 * cleared when this exception is thrown.105 */106 public final void join() throws InterruptedException {107 join(0);108 }