本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的

如图所示代码,是并行执行的

public class ThreadTest {
//private static final Long count = 10000L;
public static void main(String[] args){
long base = System.currentTimeMillis();
try {
ThreadJoin t1 = new ThreadJoin("线程1");
ThreadJoin t2 = new ThreadJoin("线程2");
t1.start();
t2.start(); } catch (Exception e) {
e.printStackTrace();
}
long time = System.currentTimeMillis() - base;
System.out.println("执行时间:"+time);
} }
class ThreadJoin extends Thread{
private static final Long count = 10L; public ThreadJoin(String name){
super(name);
} @Override
public void run() {
//super.run();
for(int i = 1; i <= count; i ++){
System.out.println(this.getName()+":"+i);
}
}
}

打印出来的信息,都是这样的

执行时间:0
线程1:1
线程2:1
线程2:2
线程2:3
线程2:4
线程2:5
线程2:6
线程2:7
线程2:8
线程2:9
线程2:10
线程1:2
线程1:3
线程1:4
线程1:5
线程1:6
线程1:7
线程1:8
线程1:9
线程1:10

要实现串行执行,可以加上join方法,实现线程1执行完成后才开始执行线程2,也就是串行执行

public class ThreadTest {
//private static final Long count = 10000L;
public static void main(String[] args){
long base = System.currentTimeMillis();
try {
ThreadJoin t1 = new ThreadJoin("线程1");
ThreadJoin t2 = new ThreadJoin("线程2");
t1.start();
t1.join();
t2.start(); } catch (Exception e) {
e.printStackTrace();
}
long time = System.currentTimeMillis() - base;
System.out.println("执行时间:"+time);
} }
class ThreadJoin extends Thread{
private static final Long count = 10L; public ThreadJoin(String name){
super(name);
} @Override
public void run() {
//super.run();
for(int i = 1; i <= count; i ++){
System.out.println(this.getName()+":"+i);
}
}
}
线程1:1
线程1:2
线程1:3
线程1:4
线程1:5
线程1:6
线程1:7
线程1:8
线程1:9
线程1:10
执行时间:0
线程2:1
线程2:2
线程2:3
线程2:4
线程2:5
线程2:6
线程2:7
线程2:8
线程2:9
线程2:10

从执行结果看,已经是串行执行线程

所以上面的例子是调了现场1的join方法,也就是说要先执行完成线程1,然后才执行main主线程

join方法的作用是,举个例子,在A线程里调B线程的join方法时,要先B线程执行完成,然后才会继续执行A线程

ok,上面调join方法是不加参数的,也可以加上参数,比如线程A.join(10);,就是说线程A执行10s后,继续执行B线程

注意:join时间参数缺省的情况,默认是0,也就是说join()等同于join(0);

/**
* Waits for this thread to die.
*
* <p> An invocation of this method behaves in exactly the same
* way as the invocation
*
* <blockquote>
* {@linkplain #join(long) join}{@code (0)}
* </blockquote>
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final void join() throws InterruptedException {
join(0);
}

Thread类里的源码,可以看出默认赋值为0,然后这个0是什么意思?0不是表示执行0s,而是表示要A线程执行完成才继续执行B线程的意思

ok,然后为什么调用了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(0);//调用线程的wait方法
}
} else {//执行时间大于0的情况
while (isAlive()) {
long delay = millis - now;//循环计算延期时间
if (delay <= 0) {
break;
}
wait(delay);//同样调用线程的wait方法
now = System.currentTimeMillis() - base;
}
}
}

ok,看了一下源码,还是比较容易理解的,其实就是调用了现场wait方法实现线程同步的

java线程join方法使用方法简介的更多相关文章

  1. 停止Java线程,小心interrupt()方法

    来源:http://blog.csdn.net/wxwzy738/article/details/8516253 程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决 ...

  2. java 多线程——join()方法

    在java语言中,join()方法的作用是让调用该方法的线程在执行完run()方法后,再执行join 方法后面的代码. 简单点说就是,将两个线程合并,用于实现同步的功能. 具体而言:可以通过线程A的j ...

  3. JAVA线程sleep和wait方法区别

    一. sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁.由于没有释放对象锁,所以不能 ...

  4. Java线程死锁查看分析方法

    如何查看是否有Java线程死锁?下面介绍两种方法. 一.Jconsole        Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输 ...

  5. Java线程 - sleep()和wait()方法的区别, 线程阻塞BLOCKED和等待WAITING的区别

    一. sleep()和wait()方法的区别 sleep()方法 sleep()方法是Thread类的方法,通过其定义可知是个native方法,在指定的时间内阻塞线程的执行.而且从其注释中可知,并不会 ...

  6. Java 线程安全的实现方法

    概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体, 程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和 ...

  7. java线程学习之wait方法

    wait 等待方法是让线程进入等待队列,使用方法是 obj.wait(); 这样当前线程就会暂停运行,并且进入obj的等待队列中,称作“线程正在obj上等待”. 如果线程想执行 wait 方法,线程必 ...

  8. [java] java 线程join方法详解

    join方法的作用是使所属线程对象正常执行run方法,而对当前线程无限期阻塞,直到所属线程销毁后再执行当前线程的逻辑. 一.先看普通的无join方法NoJoin.java public class N ...

  9. Thread之四:java线程返回结果的方法

    两种方式:一种继承Thread类实现:一种通过实现Callable接口. 第一种方法: 因为实现Thread类的run方法自身是没有返回值的,所以不能直接获得线程的执行结果,但是可以通过在run方法里 ...

随机推荐

  1. log file sync等待超高案例浅析

    监控工具DPA发现海外一台Oracle数据库服务器DB Commit Time指标告警,超过红色告警线(40毫秒左右,黄色告警是10毫秒,红色告警线是20毫秒),如下截图所示,生成了对应的时段的AWR ...

  2. Database mirroring connection error 4 'An error occurred while receiving data: '10054(An existing connection was forcibly closed by the remote host.)

    公司一SQL Server镜像发生了故障转移(主备切换),检查SQL Server镜像发生主备切换的原因,在错误日志中发现下面错误: Date        2019/8/31 14:09:17   ...

  3. diango运行流程

    diango运行流程 Django处理一个请求的流程: 在浏览器的地址栏中输入地址,回车,发了一个GET请求 wsgi模块接收了请求,将请求的相关信息封装成request对象 根据地址找到对应函数 执 ...

  4. [洛谷P1037][题解]产生数

    这道题的关键是利用Floyd算法的性质求转换方案,算是Floyd的一个变形,具体可以看代码. 题目 #include<bits/stdc++.h> using namespace std; ...

  5. Java之字符编码和字符集

    什么是字符编码 计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字.英文.标点符号.汉字等字符是二进制数转换之后的结果.按照某种规则,将字符存储到计算机中,称为编码 .反之,将存储在计算 ...

  6. windows7使用vhd虚拟磁盘

    操作系统 : windows7_x64 创建vhd 磁盘管理 --> 操作 --> 创建vhd 挂载vhd 脚本: rem 挂载VHD @echo off (echo select vdi ...

  7. javascript es6 Promise 异步同步的写法(史上最简单的教程了)

    1 来个简单的例子 var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.lo ...

  8. ETC到底要不要办?有什么好处?

    一说到ETC,开车的朋友想必不会陌生.但很多车友却不太愿意办理ETC, 究其原因,主要是一些谣言所致,一传一十传百最后变成了真实的谎言,并且对此深信不疑, 比如下面5个广泛流传的谣言     在来看看 ...

  9. SpringBoot打包为war包,并在tomcat中运行

    先看一下我创建的最简单的项目吧. controller类 @RestController public class TestController { @RequestMapping("ind ...

  10. [错误]Caused by: org.apache.spark.memory.SparkOutOfMemoryError: Unable to acquire 65536 bytes of memory, got 0

    今天,在运行Spark SQL代码的时候,遇到了以下错误: Caused by: org.apache.spark.SparkException: Job aborted due to stage f ...