join为非静态方法,定义如下:
void join(): 等待该线程终止。
void join(long millis): 等待该线程终止的时间最长为 millis 毫秒。
void join(long millis, int nanos): 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
测试代码:
- public class ThreadJoinTest {
- public static void main(String[] args) {
- ThreadA ta = new ThreadA();
- new ThreadB(ta).start();
- }
- }
- class ThreadA extends Thread {
- public void run() {
- try {
- System.out.println("runing A start^^^^^^^^^^^");
- Thread.currentThread().sleep(2000);
- System.out.println("runing A over^^^^^^^^^^^");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- class ThreadB extends Thread {
- private ThreadA ta;
- public ThreadB(ThreadA ta) {
- this.ta = ta;
- }
- public void run() {
- try {
- System.out.println("runing B start^^^^^^^^^^^");
- ta.start();
- // 在ThreaB中调用ThreadA的join(),此时的ThreadB将挂起,直到ThreadA执行结束ThreadB才继续执行
- ta.join();
- System.out.println("runing B over^^^^^^^^^^^");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
仔细分析输出将一目了然:
- runing B start^^^^^^^^^^^
- runing A start^^^^^^^^^^^
- runing A over^^^^^^^^^^^
- runing B over^^^^^^^^^^^
在 t1.start()子线程就绪;之后添加t1.join(),则等t1线程执行完之后才执行主线程
---------------
package com.wlh;
public class TestJoin {
public static void main(String[] args) {
MyThread2 t1 = new MyThread2("子线程");
t1.start();
try {
t1.join();
} catch (InterruptedException e) {}
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);//当前线程休息1000秒
System.out.println("i am main thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread2 extends Thread {
MyThread2(String s){
super(s);
}
public void run(){
for(int i =1;i<=10;i++){
System.out.println("i am "+getName());
try {
sleep(1000);//当前线程休息1000秒
} catch (InterruptedException e) {
return;
}
}
}
}
--------------------
仔细分析输出将一目了然:
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
代码如下 | 复制代码 |
package com.javaer.thread; public class Tjoin { /** * @param args */ public static void main(String[] args) { Thread t = new Thread(new Runner()); t.start(); try { t.join(1000); System.out.println("join ok"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class Runner implements Runnable { @Override public void run() { try { System.out.println("Start sleep"); Thread.sleep(1000); System.out.println("End sleep"); } catch (InterruptedException e) { e.printStackTrace(); } } } Start sleep join ok End sleep |
主线程等待1000ms,进行合并,跳回主线程,然后执行子线程
如果将
t.join(1000);
改为
t.join(2000);
主线程等待2000ms,进行合并。
结果
Start sleep
End sleep
join ok
主线程等2000,开始join。 跳回主线程,发现子线程都执行完毕了。
如果改成
t.join(0)
JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远等待.
结果
Start sleep
End sleep
join ok
其实Join方法实现是通过wait。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。
所以上面的t.join(0) 等到子线程退出以后,跳回主线程。
main 线程调用t.join时,必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t.join(1000)不是说明了main线程等待1秒,如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1秒了
代码如下 | 复制代码 |
|
获取一个锁
Start sleep
End sleep
释放锁
join ok
一个线程获取了锁,主线在join的时候,即使被join的线程结束了,因为线程被锁住,所以即使join的时间也到了,但是还是必须等待锁释放,才能被join
感谢:
http://787141854-qq-com.iteye.com/blog/2072396
http://www.111cn.net/jsp/Java/63508.htm