很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往早于子线程结束之前结束。
若主线程想等子线程运行结束后再结束,就要用到join()了,join方法的作用是等待线程对象x的销毁。即使所属线程对象x正常执行run()方法中的任务,而使当前线程z无限期的受阻,等线程x销毁后再继续执行线程z后面的代码。
方法join具有使线程排队运行的作用,类似于同步。join在内部使用wait()方法进行等待,而synchronized使用的是对象监视器原理作为同步。
在join过程中,若当前线程对象被中断,则当前线程出现异常。例如:
ThreadA.java
public class ThreadA extends Thread{
public void run(){
for(int i=0;i<Integer.MAX_VALUE;i++){
//System.out.println(i);
String string=new String();
}
}
}
ThreadB.java
public class ThreadB extends Thread{
public void run(){
try{
ThreadA a=new ThreadA();
a.start();
a.join();
System.out.println("线程B在run end处打印了");
}catch(InterruptedException e){
System.out.println("线程B在catch处打印了");
e.printStackTrace();
}
}
}
当线程B发生interrupt时,线程B会发生异常,但是线程A还会继续执行。
join(long)是设定等待时间。
join(long)和sleep(long)的区别:
join(long)的功能是在内部使用wait(long)方法来实现,所以join(long)具有释放锁的特点,sleep(long)不具有释放锁的特点。join(long)源代码如下:
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(long)与sleep(long)实例如下:
ThreadB.java
public class ThreadB extends Thread{
public void run(){
try{
System.out.println(" b run begin!");
Thread.sleep(5000);
System.out.println(" b run end!");
}catch(InterruptedException e){
e.printStackTrace();
}
}
synchronized public void bServer(){
System.out.println("打印了bServer!");
}
}
ThreadA.java
public class ThreadA extends Thread{
private ThreadB b;
public ThreadA(ThreadB b) {
super();
this.b=b;
}
public void run(){
try{
synchronized (b) {
b.start();
Thread.sleep(6000);
//b.join();
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
ThreadC.java
public class ThreadC extends Thread{
private ThreadB b;
public ThreadC(ThreadB b) {
super();
this.b=b;
}
public void run(){
b.bServer();
}
}
Run.java
public class Run {
public static void main(String[] args) throws InterruptedException{
ThreadB b=new ThreadB();
ThreadA a=new ThreadA(b);
a.start();
Thread.sleep(1000);
ThreadC c=new ThreadC(b);
c.start();
}
}
结果如下:
sleep(long)因为不释放锁,所以是同步的,现把ThreadA.java中加上b.join(),因为join(long)是释放锁的,所以运行是异步的,结果如下: