千家信息网

Java中join有什么用

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,小编给大家分享一下Java中join有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!java多线程里的join,从字
千家信息网最后更新 2024年11月19日Java中join有什么用

小编给大家分享一下Java中join有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

java多线程里的join,从字面意思来看是联合,合并的意思,但如果面试时这么回答,基本上可以断定面试者还没搞懂。join究竟能干什么,今天给出一个最通俗的解释,那就是在多线程环境下实现暂时以单线程执行,或者说在并行执行的环境中实现暂时以串行执行。为了说明这个问题,我们看一段再常见不过的代码,代码内容是,让三个线程分布去打印一段内容

//代码块1
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new DoSth());
Thread t2 = new Thread(new DoSth());
Thread t3 = new Thread(new DoSth());
t1.start();
t2.start();
t3.start();
System.out.println("主线程执行");
}
}

class DoSth implements Runnable {
@Override
public void run() {
int n = 5;
while (n > 0) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
n--;
}
}
}

执行结果如下:

线程1执行
线程2执行
线程3执行
线程2执行
线程3执行
线程1执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程1执行
线程1执行
线程1执行

可见三个线程各自并行执行,并无明确的先后顺序。但如果我们在t.start()后面加上这行代码,

//代码块2
t1.start();
t1.join();

看会出现看什么样的结果:

线程1执行
线程1执行
线程1执行
线程1执行
线程1执行
线程2执行
线程3执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行

可以看到线程1执行结束之后线程2和3才开始执行,可见在线程1执行过程中,其他线程并未执行,线程1结束后,线程2,线程3开始并行执行,这就印证了前面的结论,即:join的作用是在多线程环境下暂时以单线程执行。明白了这一点,接下来的问题是,这个特性是怎么实现的呢?我们跟到源码:可以看到

//代码块3

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;
}
}

}

在第12行调用了wait,注意这里的wait,它并不是指线程线程1对象执行wait,而是线程1的调用者,也就是相当于在主线程去执行wait,可等价理解为以下伪代码:

t1.start();
while(t1.isAlive()){
Thread.currentThread().doWait()
}

此时执行流程会在代码块3的11-13行循环执行,当线程1执行完毕时,其生命周期结束,isAlive()返回false,11-13行退出循环,继续执行下面的代码,此时又切换为并行执行状态。对于以上执行效果,我们完全可以不用创建t1线程,而是把在主线程中直接去调用t1的核心逻辑,代码如下:

public static void main(String[] args) throws InterruptedException {
//Thread t1 = new Thread(new DoSth(), "线程1");
Thread t2 = new Thread(new DoSth(), "线程2");
Thread t3 = new Thread(new DoSth(), "线程3");
//t1.start();
//t1.join();
new DoSth().run();//直接调用业务逻辑,而不是分配线程去执行
t2.start();
t3.start();
System.out.println("主线程执行");
}

和之前的代码相比,本来需要在子线程t1中执行的内容,通过在主线程中执行达到了相同的效果,而这种特性,就体现了所谓的join,现在你明白为什么叫join了吧?join在实际应用当中有什么用呢?把以上代码改造一下,用一个例子来说明。

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new DoSth(), "小组1");
Thread t2 = new Thread(new DoSth(), "小组2");
Thread t3 = new Thread(new DoSth(), "小组3");
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println("集合完毕");
}

执行结果:

小组3正在集合
小组1正在集合
小组2正在集合
小组3正在集合
小组1正在集合
小组2正在集合
小组3正在集合
小组1正在集合
集合完毕

当我们需要多个子线程分布去完成各自的任务,并在这些子线程全部完成后,主线程做统一汇总时,join就派上用场了。不过细心的读者会发现,这些子线程并未返回任何结果,如果我们需要返回结果供主线程使用时,该怎么实现,针对这一需求,单靠实现Runnable的方式已经无法做到了,此时需要用到另外的接口:Feature和Callable。

以上是"Java中join有什么用"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

线程 代码 小组 正在 内容 结果 环境 篇文章 三个 意思 效果 特性 而是 逻辑 问题 循环 相同 细心 通俗 接下来 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳哈稀网络技术有限公司面试 网络安全应急实战 交通银行软件开发校招有编制吗 数据库设计学生教师实例 榆林软件开发培训公司 数据库技术学习方法 电脑用的招教软件开发 公安哪个部门管网络安全 上海财经大学网络安全知识竞赛 护苗 网络安全课2020 数据库开发到底是什么 数据库弄点数据冗余 node.js数据库连接池 网络安全大赛用什么代码 浙江交友软件开发费用是多少 统计数据可以用什么数据库 福建省网络安全测评中心 一流的管理与服务器 蓟州教育网网络安全 小学网络安全知识内容手抄报 锐捷网络技术教程 背水一战下载软件开发 极限生存手机版服务器 网络安全机密性概念 持久化存储具体包括文件和数据库 电子科技大学研究生网络安全专业 四川视觉引导点胶软件开发 查询oralce数据库死锁 世界网络安全人人有责 火传媒上海互联网科技
0