栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

join 原理手撕JDK8 源码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

join 原理手撕JDK8 源码

join 原理手撕JDK8 源码

当一回标题党,希望内容对道友们有所帮助

原版现象
  1. 示例代码
// 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();
        }
    }
}
  1. 编译运行
# 编译代码
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;
        }
    }
}
模拟总结
  1. 模拟代码
// 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);
        }
    }
}
  1. 运行总结
# 编译代码
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()的用法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/396736.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号