引入
在很多情况下,主线程创建并启动子线程,如果子线程要进行大量的耗时计算,主线程往往将早于子线程结束之前结束。这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据的值,就要用到join()方法了。方法join()的作用是等待线程对象销毁。
使用的主要的类
public class MyObject {
private int value;
public void setValue(int value){
System.out.println("set value:"+value);
this.value=value;
}
public int getValue(){
return value;
}
}
没有使用join方法的情况
这种情况下演示,需求是主线程要在子线程给MyObject赋值后拿到MyObject对象的值,没有使用join()方法会导致主线程会在子线程之前就结束。
子线程的代码:
public class MyThread extends Thread{
private MyObject mo;
public MyThread(MyObject mo){
this.mo=mo;
}
public void run(){
mo.setValue(100);
}
}
运行的代码
public class Run {
public static void main(String[] args) {
MyObject mo=new MyObject();
MyThread mt=new MyThread(mo);
mt.start();
int value=mo.getValue();
System.out.println("get value:"+value+" main thread end.");
}
}
运行结果为:
get value:0 main thread end.
set value:100
2.用join()方法类解决
join()方法的作用是使所属的线程对象x正常执行run()方法中的人物,而使当前线程z
进行无限期的阻塞,等待线程x销毁后在继续执行线程z后面的代码。使线程具有排队运行的作用,有着类似同步的运行效果。
public class Run {
public static void main(String[] args) {
try {
MyObject mo = new MyObject();
MyThread mt = new MyThread(mo);
mt.start();
mt.join(); //使用join()方法,先执行完mt线程的run方法中的任务
int value = mo.getValue();
System.out.println("get value:" + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
set value:100
get value:100
其他注意的点
- 在join过程中,如果当前线程对象被中断,则当前线程出现异常,InterruptedException。
- 方法join(long)中的参数是设置等待的时间。
- 方法join(long)的功能在内部是使用wait(long)方法来实现的,所以join(long)方法具有释放锁的特点,而Thread.sleep(long)方法具有不释放锁的特点。