1. Thread.join方法
join()
方法会等待指定线程结束,然后才会继续运行。
public class ThreadJoin {
public static void main(String[] args) {
try {
ThreadA threadA = new ThreadA();
threadA.start();
System.out.println("In Main begin at " + System.currentTimeMillis());
threadA.join();
System.out.println("In Main end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
static class ThreadA extends Thread {
public void run() {
try {
System.out.println("In ThreadA begin at " + System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("In ThreadA end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
}
输出
2. join(long)方法
join(long)
方法会等待指定线程一段时间,然后进入运行状态。
将上面的threadA.join()
修改成以下代码,
threadA.join(2000);
输出
如果是等待4秒,在3秒时就返回并结束程序。
3. join方法解析
join()
方法会调用join(0)
,而join(long)
在源码里如此实现。
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;
}
}
}
如果millis
为0,直接调用wait(0)
,否则在等待指定时间后返回。而Thread
结束线程后,会调用唤醒所有等待列表中的线程。
public class ThreadFinishWait {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.start();
new ThreadB(threadA).start();
new ThreadB(threadA).start();
}
static class ThreadA extends Thread {
public void run() {
try {
System.out.println("In ThreadA begin at " + System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("In ThreadA end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
static class ThreadB extends Thread {
ThreadA threadA;
public ThreadB(ThreadA threadA) {
this.threadA = threadA;
}
public void run() {
synchronized (threadA) {
try {
System.out.println("In ThreadB begin at " + System.currentTimeMillis());
threadA.wait();
System.out.println("In ThreadB end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
}
}
输出
join()
方法中调用了线程的wait()
方法,因此要小心对线程对象锁的使用,以免造成一些意外。
public class ThreadJoinError {
public static void main(String[] args) {
try {
ThreadA threadA = new ThreadA();
threadA.start();
ThreadB threadB = new ThreadB(threadA);
threadB.start();
System.out.println("In Main begin at " + System.currentTimeMillis());
threadA.join();
System.out.println("In Main end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
static class ThreadA extends Thread {
public void run() {
try {
System.out.println("In ThreadA begin at " + System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("In ThreadA end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
static class ThreadB extends Thread {
ThreadA threadA;
ThreadB(ThreadA threadA) {
this.threadA = threadA;
}
public void run() {
synchronized (threadA) {
try {
System.out.println("In ThreadB begin at " + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("In ThreadB end at " + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
}
}
输出
线程ThreadB
获取了ThreadA
的线程锁,join()
方法需要等待ThreadB
释放线程锁后才能完成执行。
相关文章
Java Thread.wait和Thread.notify方法
Java Thread.join方法
Java Thread.sleep方法
Java Thread.Interrupt方法
Java Lock对象