当一回标题党,希望内容对道友们有所帮助
原版现象- 示例代码
// TT01.java
public class TT01 {
public static void main(String []args) throws Exception {
Thread tt = new Thread(() -> {
try {
for (int i=0; i<5; i++) {
System.out.println("tt thread: " + i);
Thread.sleep(50);
}
} catch (Exception e) {
e.printStackTrace();
}
});
tt.start();
for (int i=0; i<10; i++) {
System.out.println("Main thread: " + i);
if (i==5) tt.join();
}
}
}
- 编译运行
# 编译代码 javac TT01.java # 运行程序 java TT01 # 运行结果 tt thread: 0 Main thread: 0 Main thread: 1 Main thread: 2 Main thread: 3 Main thread: 4 Main thread: 5 tt thread: 1 tt thread: 2 tt thread: 3 tt thread: 4 # <---- 线程tt 结束 Main thread: 6 # <---- 线程Main 继续 Main thread: 7 Main thread: 8 Main thread: 9 ## 在Main 调用tt.join() 之前(i != 5), 线程Main 与线程tt 并行 ## 在Main 调用tt.join() 之后(i == 5), 先线程tt,完毕后再执行线程Main ## 从表面上看,仿佛join() 将tt 线程的运行内容并入了Main 线程一般 ## 无论执行多少次,都会在"tt thread: 4"之后才打印"Main thread: 6"等内容源码参考
// JDK8 中Thread 的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;
}
}
}
模拟总结
- 模拟代码
// TT02.java
public class TT02 {
public static void main(String []args) throws Exception {
TT tt = new TT();
tt.setName("TT thread");
tt.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main: " + i);
if (i == 5)
tt.dloop();
}
}
}
// 自定义线程类
class TT extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + ": " + i);
sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 模拟join() 的方法
public void dloop() throws InterruptedException {
// 本线程销毁前一直循环
while (this.isAlive()) {
sleep(5);
}
}
}
- 运行总结
# 编译代码 javac TT02.java # 运行程序 java TT02 # 执行结果 TT thread: 0 Main: 0 Main: 1 Main: 2 Main: 3 Main: 4 Main: 5 TT thread: 1 TT thread: 2 TT thread: 3 TT thread: 4 # <---- 线程TT 结束 Main: 6 # <---- 线程Main 继续 Main: 7 Main: 8 Main: 9 ## 模拟代码同样也达到了JDK8 中Thread 类join() 方法的效果,基本思路就是 ## Thread 的子类对象提供一个方法,例如模拟代码里的dloop() 让Main 线程调用 ## 将Main 线程带沟里,让其运行一个死循环,对应的线程不结束该循环就一直继续下去 ## 所以,当我们看到Main 线程调用join() 后就阻塞了,实际上是Main 线程掉入了死循环里 ## 从模拟代码也可以看出join() 的核心并不是synchronized 和wait() 来控制锁,而是那个死循环 ## 当然为了让线程安全synchronized 和wait() 以及线程结束后调用的notifyAll() 都是必不可少的参考资料
Java 浅析 Thread.join()
Thread之三:Thread Join()的用法



