Join()
Join使用方法:
主线程创建并启动子线程,如果子线程中要进行大量的耗时计算,主线程往往早于子线程结束,如果主线程想等待子线程执行完成后再结束,比如需要获得子线程处理的数据,就需要用到join()。
验证代码:
public class MyThread extends Thread {
@Override
public void run() {
try {
int secondValue = (int) (Math.random() * 10000);
System.out.println(secondValue);
Thread.sleep(secondValue);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import extthread.MyThread;
public class Test {
public static void main(String[] args) {
try {
MyThread threadTest = new MyThread();
threadTest.start();
threadTest.join();
System.out.println("1111");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
5861
1111
Join与异常
主线程中,调用两个子线程,当一个线程遇到interrupt(),则该线程终端,抛出异常,但并不影响另一个子线程和主线程。
验证代码:
public class ThreadA extends Thread {
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String newString = new String();
Math.random();
}
}
}
public class ThreadB extends Thread {
@Override
public void run() {
try {
ThreadA a = new ThreadA();
a.start();
a.join();
System.out.println("B run over");
} catch (InterruptedException e) {
System.out.println("B interrupt");
e.printStackTrace();
}
}
}
public class ThreadC extends Thread {
private ThreadB threadB;
public ThreadC(ThreadB threadB) {
super();
this.threadB = threadB;
}
@Override
public void run() {
threadB.interrupt();
System.out.println("C run ");
}
}
import extthread.ThreadB;
import extthread.ThreadC;
public class Run {
public static void main(String[] args) {
try {
ThreadB b = new ThreadB();
b.start();
Thread.sleep(500);
ThreadC c = new ThreadC(b);
c.start();
System.out.println("main run over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Thread.join(Thread.java:1249)
at java.lang.Thread.join(Thread.java:1323)
at extthread.ThreadB.run(ThreadB.java:10)
main run over
C run
B interrupt
Join(long)和wait(long)的区别:
Join(long)和wait(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;
}
}
}
json是通过wait(long)来实现,wait(long)会释放锁。
join(long)和sleep(long)的区别:
join(long):当前线程的锁被释放,其他现场可以调用此线程的同步方法。
Sleep(long):不释放锁。
因此join和sleep的主要却别在于对同步的处理上。
具体看代码:
public class ThreadA extends Thread {
private ThreadB b;
public ThreadA(ThreadB b) {
super();
this.b = b;
}
@Override
public void run() {
try {
synchronized (b){
b.start();
Thread.sleep(6000);
}
// Thread.sleep()不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadB extends Thread {
@Override
public void run() {
try {
System.out.println(" b run begin timer="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println(" b run end timer="
+ System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void bService() {
System.out.println("打印了bService timer=" + System.currentTimeMillis());
}
}
public class ThreadC extends Thread {
private ThreadB threadB;
public ThreadC(ThreadB threadB) {
super();
this.threadB = threadB;
}
@Override
public void run() {
threadB.bService();
}
}
public class Run {
public static void main(String[] args) {
try {
ThreadB b = new ThreadB();
ThreadA a = new ThreadA(b);
a.start();
Thread.sleep(1000);
ThreadC c = new ThreadC(b);
c.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:验证sleep不释放锁
b run begin timer=1535027906244
(间隔5s,6s后释放锁)
b run end timer=1535027911245
打印了bService timer=1535027912244
将ThreadA 中的Thread.sleep(6000)修改为b.join(6000)。
public class ThreadA extends Thread {
private ThreadB b;
public ThreadA(ThreadB b) {
super();
this.b = b;
}
@Override
public void run() {
try {
synchronized (b){
b.start();
b.join(6000);
}
// Thread.sleep()不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
b run begin timer=1535028336151
间隔1s
打印了bService timer=1535028337153
b run end timer=1535028341151