join的简单总结

BAT面试题:现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?

这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。这个多线程问题比较简单,可以用join方法实现。

 

一、作用

Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。具体看代码:

 1 public class JoinTest {
 2     public static void main(String [] args) throws InterruptedException {
 3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
 4         ThreadJoinTest t2 = new ThreadJoinTest("小东");
 5         t1.start();
 6         /**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是:
 7          程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
 8          所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会
 9          */
10         t1.join();
11         t2.start();
12     }
13 
14 }
15 class ThreadJoinTest extends Thread{
16     public ThreadJoinTest(String name){
17         super(name);
18     }
19     @Override
20     public void run(){
21         for(int i=0;i<1000;i++){
22             System.out.println(this.getName() + ":" + i);
23         }
24     }
25 }

上面程序结果是先打印完小明线程,在打印小东线程;  

上面注释也大概说明了join方法的作用:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。注意,这里调用的join方法是没有传参的,join方法其实也可以传递一个参数给它的,具体看下面的简单例子:

 1 public class JoinTest {
 2     public static void main(String [] args) throws InterruptedException {
 3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
 4         ThreadJoinTest t2 = new ThreadJoinTest("小东");
 5         t1.start();
 6         /**join方法可以传递参数,join(10)表示main线程会等待t1线程10毫秒,10毫秒过去后,
 7          * main线程和t1线程之间执行顺序由串行执行变为普通的并行执行
 8          */
 9         t1.join(10);
10         t2.start();
11     }
12 
13 }
14 class ThreadJoinTest extends Thread{
15     public ThreadJoinTest(String name){
16         super(name);
17     }
18     @Override
19     public void run(){
20         for(int i=0;i<1000;i++){
21             System.out.println(this.getName() + ":" + i);
22         }
23     }
24 }

上面代码结果是:程序执行前面10毫秒内打印的都是小明线程,10毫秒后,小明和小东程序交替打印。

所以,join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。

 

二、join与start调用顺序问题

上面的讨论大概知道了join的作用了,那么,如果 join在start前调用,会出现什么后果呢?先看下面的测试结果

 1 public class JoinTest {
 2     public static void main(String [] args) throws InterruptedException {
 3         ThreadJoinTest t1 = new ThreadJoinTest("小明");
 4         ThreadJoinTest t2 = new ThreadJoinTest("小东");
 5         /**join方法可以在start方法前调用时,并不能起到同步的作用
 6          */
 7         t1.join();
 8         t1.start();
 9         //Thread.yield();
10         t2.start();
11     }
12 
13 }
14 class ThreadJoinTest extends Thread{
15     public ThreadJoinTest(String name){
16         super(name);
17     }
18     @Override
19     public void run(){
20         for(int i=0;i<1000;i++){
21             System.out.println(this.getName() + ":" + i);
22         }
23     }
24 }

上面代码执行结果是:小明和小东线程交替打印。

所以得到以下结论:join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。

 

三、join方法实现原理

有了上面的例子,我们大概知道join方法的作用了,那么,join方法实现的原理是什么呢?

其实,join方法是通过调用线程的wait方法来达到同步的目的的。例如,A线程中调用了B线程的join方法,则相当于A线程调用了B线程的wait方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态,具体看下面的源码:

 1 public final synchronized void join(long millis)
 2     throws InterruptedException {
 3         long base = System.currentTimeMillis();
 4         long now = 0;
 5 
 6         if (millis < 0) {
 7             throw new IllegalArgumentException("timeout value is negative");
 8         }
 9 
10         if (millis == 0) {
11             while (isAlive()) {
12                 wait(0);
13             }
14         } else {
15             while (isAlive()) {
16                 long delay = millis - now;
17                 if (delay <= 0) {
18                     break;
19                 }
20                 wait(delay);
21                 now = System.currentTimeMillis() - base;
22             }
23         }
24     }

从源码中可以看到:join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/277457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python numpy矩阵索引_python – Numpy中的矩阵索引

索引后查看形状&#xff1a;In [295]: Anp.matrix([1,2,3])In [296]: A.shapeOut[296]: (1, 3)In [297]: A[0]Out[297]: matrix([[1, 2, 3]])In [298]: A[0].shapeOut[298]: (1, 3)这种行为的关键是np.matrix总是2d.所以即使你选择一行(A [0,&#xff1a;]),结果仍然是2d,形状(…

Activity的呼叫转移*(3个Activity之间的跳转)

Redirection的意思就是“呼叫转移&#xff0c;重寄”的意思 我们也许会再程序开发中遇到这种情况&#xff0c;需要从一个Activity&#xff08;A&#xff09;跳转到另一个Activity&#xff08;B&#xff09;&#xff0c;当在这个Activity&#xff08;B&#xff09;中处理完一些操…

深度解析数据分析、大数据工程师和数据科学家的区别

数据越来越多的影响并塑造着那些我们每天都要交互的系统。不管是你使用Siri&#xff0c;google搜索&#xff0c;还是浏览facebook的好友动态&#xff0c;你都在消费者数据分析的结果。我们赋予了数据如此大的转变的能力&#xff0c;也难怪近几年越来越多的数据相关的角色被创造…

python webservice接口测试传参数_Python3 webservice接口测试方法是什么

Python3 webservice接口测试方法是什么发布时间&#xff1a;2020-06-23 14:07:46来源&#xff1a;亿速云阅读&#xff1a;92作者&#xff1a;清晨不懂Python3 webservice接口测试方法是什么&#xff1f;其实想解决这个问题也不难&#xff0c;下面让小编带着大家一起学习怎么去解…

zabbix4.2 系列(二):agent配置

zabbix-agent&#xff1a; 分为主动模式和被动模式&#xff0c;均在配置文件实现&#xff08;主动模式和被动模式可同时设置&#xff09;&#xff1a; vim /etc/zabbix/zabbix_agentd.conf Server192.168.18.154 &#xff08;用于被动模式&#xff0c;允许哪台服务器可以…

java form 对象 一对一_java-双向一对一地“对象引用了一个未保存...

我有一个简单的一对一关系&#xff1a;>为每个实体单独的DAO.>事务由Spring管理.PersonDao personDao ctx.getBean(PersonDao.class, "personDaoImpl");VehicleDao vehicleDao ctx.getBean(VehicleDao.class, "vehicleDaoImpl");Vehicle vehicle …

RabbitMQ 入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)

发布&#xff0f;订阅 在上篇第二部分教程中&#xff0c;我们搭建了一个工作队列。每个任务之分发给一个工作者&#xff08;worker&#xff09;。在本篇教程中&#xff0c;我们要做的之前完全不一样——分发一个消息给多个消费者&#xff08;consumers&#xff09;。这种模式被…

Proxmox VE 安装、配置、使用之第二章 Proxmox VE 的安全性

第一章 Proxmox VE 的安全性一、 角色及权限图2-1-1二、 Root 的密码安全性把 Root 的实际密码给出去, 在任何系统都是不符合安全规范的!所以在 Linux 里面, 最好把有需要 root 权限的使用者 放到 sudoers 的群组.# sudo usermod -a -G sudo testuserPVE 的权限设定方式 是由 u…

java allocate_Java中volatile关键字的最全总结

一、简介volatile是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制&#xff1a;同步块(或方法)和 volatile 变量&#xff0c;相比于synchronized(synchronized通常称为重量级锁)&#xff0c;volatile更轻量级&#xff0c;因为它不会引起线程上下文的切换和调…

缩放手势 ScaleGestureDetector 源码解析,这一篇就够了

其实在我们日常的编程中&#xff0c;对于缩放手势的使用并不是很经常&#xff0c;这一手势主要是用在图片浏览方面&#xff0c;比如下方例子。但是&#xff08;敲重点&#xff09;&#xff0c;作为 Android 入门的基础来说&#xff0c;学习 ScaleGestureDetector 的使用&#x…

postgres的数据库备份和恢复

备份和恢复 一条命令就可以解决很简单: 这是备份的命令&#xff1a; pg_dump -h 127/0.0.1 -U postgres databasename > databasename.bak 指令解释&#xff1a; pg_dump 是备份数据库指令&#xff0c;164.82.233.54是数据库的ip地址&#xff08;必须保证数据库允许外部访…

java 类的执行顺序_Java中类的执行顺序

讲解在代码中&#xff1a;package 类执行顺序;/*** java类执行顺序** 1、如果父类有静态成员赋值或者静态初始化块&#xff0c;执行静态成员赋值和静态初始化块* 2、如果类有静态成员赋值或者静态初始化块&#xff0c;执行静态成员赋值和静态初始化块* 3、将类的成员赋予初值(原…

ZooKeeper相关资料集锦

1、ZooKeeper相关概念总结 https://github.com/Snailclimb/JavaGuide/blob/master/docs/system-design/framework/ZooKeeper.md 2、ZooKeeper在Windows下的安装和配置 https://blog.csdn.net/morning99/article/details/40426133 3、Curator框架应用 http://ifeve.com/zookeepe…

JQuery.Ajax()的data参数传递方式

最近&#xff0c;新学c# mvc&#xff0c;通过ajax post方式传递数据到controller。刚开始传递参数&#xff0c;controller中总是为null。现记录一下&#xff0c;可能不全&#xff0c;纯粹记个学习日记。 重点在于参数的方式&#xff0c;代码为例子 1、这里 dataType: "js…

java如何实现封装_java如何实现封装

Java中类的封装是如何实现的封装是将对象的信息隐藏在对象内部&#xff0c;禁止外部程序直接访问对象内部的属性和方法。 java封装类通过三个步骤实现&#xff1a; (1)修改属性的可见性&#xff0c;限制访问。 (2)设置属性的读取方法。 (3)在读取属性的方法中&#xff0c;添加对…

用了30天整理的一些GO语言学习资料,2019请你加油

因为极其优秀的并发性能&#xff0c;Google的亲儿子Go语言站上了风潮之巅。出现在21世纪的GO语言&#xff0c;虽然不能如愿对C取而代之&#xff0c;但是其近C的执行性能和近解析型语言的开发效率以及近乎于完美的编译速度&#xff0c;已经风靡全球。特别是在云项目中&#xff0…

Kubernetes网络设计原则

在配置集群网络插件或者实践K8S 应用/服务部署请时刻想到这些原则&#xff1a; 1.每个Pod都拥有一个独立IP地址&#xff0c;Pod内所有容器共享一个网络命名空间2.集群内所有Pod都在一个直接连通的扁平网络中&#xff0c;可通过IP直接访问 所有容器之间无需NAT就可以直接互相访问…

php token 验证,PHP如何实现Token验证

PHP如何实现Token验证首先将Token进行解析&#xff1b;然后根据解析出来的信息部分验证是否过期&#xff0c;如果未过期再将解析出的信息部分进行加密&#xff1b;最后将加密出来的数据和解析出来签名进行比对&#xff0c;如果相同则验证成功。示例代码&#xff1a;<?php f…

关于Linux fontconfig 字体库的坑

01、安装字体软件yum -y install fontconfig然后把字体拷过去就行了 cd /usr/share/fonts fc-list 这是查看02、拷贝字体到指定目录 cp simsun.ttc /usr/share/fonts/然后把字体拷过去就行了 cd /usr/share/fonts 03、验证字体安装情况 fc-list //"宋体"中文字体…

满江红.互联网

小小寰球&#xff0c;有多少信息瞬抵。互联网&#xff0c;几多涛生&#xff0c;几多云逸。蚂蚁缘槐近大国&#xff0c;菜鸟搭枝成凤翼。正台风绿叶下临安&#xff0c;何足惧?多少事&#xff0c;从来急&#xff1b;天地转&#xff0c;光阴隙。一百年太久&#xff0c;只争朝夕。…