join()的使用
join的作用
join的作用是等待线程对象销毁。
方法join 的作用是使所属的线程对象 x 正常执行 run() 方法中的任务,而使当前线程 z 进行无限期的阻塞,等待线程 x 销毁之后再继续执行当前线程 z 后面的代码。
注意:
如果方法 join() 与 interrupt() 方法相遇,则会抛出异常。示例如下:
public class JoinException {
public static void main(String[] args) {
try {
ThreadB b = new ThreadB();
b.start();
Thread.sleep(500);
ThreadC c = new ThreadC(b);
c.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class ThreadA extends Thread {
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String newString = new String();
Math.random();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
try {
Thread a = new ThreadA();
a.start();
a.join();
System.out.println("线程B在 run end 处打印了");
} catch (InterruptedException e) {
System.out.println("线程B在 catch 处打印了");
e.printStackTrace();
}
}
}
static class ThreadC extends Thread {
private ThreadB threadB;
public ThreadC(ThreadB threadB) {
this.threadB = threadB;
}
@Override
public void run() {
threadB.interrupt();
}
}
}
运行结果如下:
join()会释放锁
Thread.sleep()不释放锁。而 join() 方法会释放锁
方法 join(long) 的功能在内部是使用 wait(long) 方法来实现的,所以 join(long) 方法具有释放锁的特点。
方法 join(long) 源代码如下:
方法 join() 后面代码提前运行:出现意外
join(long millis) 设置了时间参数的 join() 容易出现意外。示例如下:
tips:最后的解决方案是把 b.join(2000) 替换成 b.join()
public class JoinTest {
public static void main(String[] args) {
try {
ThreadB b = new ThreadB();
ThreadA a = new ThreadA(b);
a.start();
b.start();
b.join(2000);
System.out.println(" main edn " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class ThreadA extends Thread {
private ThreadB b;
public ThreadA(ThreadB b) {
this.b = b;
}
@Override
public void run() {
synchronized (b) {
try {
System.out.println("begin A ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(" end A ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class ThreadB extends Thread {
@Override
synchronized public void run() {
try {
System.out.println("begin B ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(" end B ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果分析: