1.join()方法介绍
join():使所属的线程对象x正常执行run()方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行z后面的代码。
join(long):等待一定时间。
- 在join过程中,如果当前线程被中断,则当前线程出现异常,但join所属的线程继续运行。
- join()在内部使用wait()方法进行等待,所以会释放锁
package chapter3.join;
public class MyThread extends Thread{
@Override
public void run() {
super.run();
try {
int secondValue = (int) (Math.random()*10000);
System.out.println(secondValue);
Thread.sleep(secondValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package chapter3.join;
public class Test {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
myThread.join();
System.out.println("MyThread 执行完之后执行!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
9574
MyThread 执行完之后执行!
2.join()方法后面的代码提前运行
join()方法源码:
//不带参数
public final void join() throws InterruptedException {
join(0);
}
//带参数
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;
}
}
}
package chapter3.join;
public class ThreadA extends Thread{
private ThreadB threadB;
public ThreadA(ThreadB threadB) {
this.threadB = threadB;
}
@Override
public void run() {
super.run();
try {
synchronized (threadB) {
System.out.println("begin A ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("end A ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package chapter3.join;
public class ThreadB extends Thread{
@Override
synchronized public void run() {
try {
super.run();
System.out.println("begin B ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("end B ThreadName="+Thread.currentThread().getName()+"--"+System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
package chapter3.join;
public class Test {
public static void main(String[] args) {
try {
ThreadB threadB = new ThreadB();
ThreadA threadA = new ThreadA(threadB);
threadA.start();
threadB.start();
threadB.join(2000);
System.out.println("main end:"+System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果1:
begin A ThreadName=Thread-1--1561019085673
end A ThreadName=Thread-1--1561019088673
main end:1561019088673
begin B ThreadName=Thread-0--1561019088673
end B ThreadName=Thread-0--1561019091673
- threadB.join(2000)先抢到threadB锁,然后释放;
- ThreadA抢到锁,打印begin,sleep;
- 打印end,释放锁;
- threadB.join(2000)和ThreadB争抢锁,join再次抢到,发现时间已过,释放然后打印main end;
- ThreadB抢到锁,打印begin,end;
运行结果2:
begin A ThreadName=Thread-1--1561019572226
end A ThreadName=Thread-1--1561019575226
begin B ThreadName=Thread-0--1561019575226
end B ThreadName=Thread-0--1561019578226
main end:1561019578226
- threadB.join(2000)先抢到threadB锁,然后释放;
- ThreadA抢到锁,打印begin,sleep;
- 打印end,释放锁;
- threadB.join(2000)和ThreadB争抢锁,ThreadB抢到,打印begin,sleep,打印end后释放锁;
- mian end最后输出;