开发中使用多线程也非常少,之前因为有一个调取两个摄像头获取每帧进行活体检测时候,有人给了思路说到Join这个关键字,我才仔细的研究了一下这个。以前理解的意思是:使用join关键字,就是相当于调用join的线程如果没有执行完毕,其他线程都处于等待状态。这就相当是把线程串起来了一样。看了很多的博客,后面理解的是:那个线程等待挂起,取决与在那个线程上面调用XX.join,并不是影响到所有的线程。
- 代码演示(正常线程执行)
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("A" + "-" + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("B" + "-" + i);
}
});
t1.start();
t2.start();
}
console
A-1
B-1
B-2
B-3
B-4
B-5
A-2
A-3
A-4
A-5
- 当在t2线程前面使用join
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("A" + "-" + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("B" + "-" + i);
}
});
t1.start();
t1.join();
t2.start();
}
console
A-1
A-2
A-3
A-4
A-5
B-1
B-2
B-3
B-4
B-5
当在t2线程前面,main线程调用了t1线程的join,所以会让main线程暂时挂起。从而需要等到t1线程死亡之后才可以唤醒main线程继续执行下去
- 当把join放在t2线程后面
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("A" + "-" + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("B" + "-" + i);
}
});
Thread t3 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("C" + "-" + i);
}
});
t1.start();
t2.start();
t1.join();
t3.start();
}
console
A-1
A-2
B-1
A-3
B-2
A-4
B-3
B-4
B-5
A-5
C-1
C-2
C-3
C-4
C-5
无论执行多次,都可证实一点,在main线程中调用xx.join的时候挂起的是main线程,但是挂起main线程之前的执行的线程不受影响。
Join的源码
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");
}
//执行时间为0或者缺省情况
if (millis == 0) {
//判断线程是否处于活动状态
while (isAlive()) {
//调用线程的wait方法
wait(0);
}
} else {
//判断线程是否处于活动状态
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
//调用线程的wait方法
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
wait()的作用是让当前线程去等待。wait方法是object类中的方法,调用该方法是让获得当前对象锁的线程等待,而在t1.join()时,是在主线程中进行调用了,主线程获得join方法上的对象锁。
isAlive()这个方法调用的是t1从Thread类中继承的native方法,是一种普通的方法调用,所以它判断的是t1线程是否还存活。