浅谈java线程join方法使用方法

本博客简介介绍一下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.join();
      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);
    }
  }
}

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

执行时间: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.join();
      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方法实现线程同步的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java join 线程控制用法

    JDK说明: joinpublic final void join()                throws InterruptedException等待该线程终止. 抛出:InterruptedException - 如果任何线程中断了当前线程.当抛出该异常时,当前线程的中断状态 被清除测试代码: 复制代码 代码如下: public class MyThread extends Thread { public static void main(String[] args) throws

  • Java多线程join方法实例代码

    本文研究的主要是Java多线程中join方法的使用问题,以下文为具体实例. Thread的非静态方法join()让一个线程B"加入"到另外一个线程A的尾部.在A执行完毕之前,B不能工作.例如: Thread t = new MyThread(); t.start(); t.join(); 另外,join()方法还有带超时限制的重载版本. 例如t.join(5000);则让线程等待5000毫秒,如果超过这个时间,则停止等待,变为可运行状态. 线程的加入join()对线程栈导致的结果是线程

  • Java线程编程中isAlive()和join()的使用详解

    一个线程如何知道另一线程已经结束?Thread类提供了回答此问题的方法. 有两种方法可以判定一个线程是否结束.第一,可以在线程中调用isAlive().这种方法由Thread定义,它的通常形式如下: final boolean isAlive( ) 如果所调用线程仍在运行,isAlive()方法返回true,如果不是则返回false.但isAlive()很少用到,等待线程结束的更常用的方法是调用join(),描述如下: final void join( ) throws InterruptedE

  • 浅谈java多线程 join方法以及优先级方法

    join: 当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果该线程冻结了,主线程就挂了,这也是为什么线程要抛异常的原因 2.当两个或以上线程开启了,这个A线程才使用join方法,那么主线程还是停下,这几个个线程交替进行,直到A执行完,主线程才复活 1. tostring(),方法,获取线程具体的名字,优先级 2. 优先级代表抢资源的频率 3. java中设置有

  • Java多线程中关于join方法的使用实例解析

    先上代码 新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String name; public MyThread(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(name+"[&

  • Java中join线程操作实例分析

    本文实例讲述了Java中join线程操作.分享给大家供大家参考,具体如下: 一 点睛 Tread提供了让一个线程等待另外一个线程完成的方法--join()方法.当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完后为止. join()方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程.当所有小问题都得到处理后,再调用主线程来进一步操作. 二 代码 public class JoinThread ext

  • java多线程编程之join方法的使用示例

    在上面的例子中多次使用到了Thread类的join方法.我想大家可能已经猜出来join方法的功能是什么了.对,join方法的功能就是使异步执行的线程变成同步执行.也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用join方法.如果不使用join方法,就不能保证当执行到start方法后面的某条语句时,这个线程一定会执行完.而使用join方法后,直到这个线程退出,程序才会往下执行.下面的代码演示了join的用法.

  • 浅谈java线程join方法使用方法

    本博客简介介绍一下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

  • 浅谈Java数组的一些使用方法及堆栈存储

    数组 用于存储一组同一数据类型数据的容器 数组会对放入其中的数据自动编号,编号是从0开始的---下标 定义格式 数据类型[] 数组名 = new 数据类型[数组的大小];---可以先声明再初始化 int[] arr = new int[5];---定义了一个最多能存储5的整数的数组 arr[3] = 4; arr[3]---通过数组名[下标]的形式来获取数组元素或者给对应的位置赋值 数据类型[] 数组名 = new 数据类型[]{元素1,元素2--}; int[] arr = new int[]

  • 浅谈JAVA 线程状态中可能存在的一些误区

    BLOCKED 和 WAITING 的区别 BLOCKED 和 WAITING 两种状态从结果上来看,都是线程暂停,不会占用 CPU 资源,不过还是有一些区别的 BLOCKED 等待 Monitor 锁的阻塞线程的线程状态,处于阻塞状态的线程正在等待 Monitor 锁进入 synchronized   Block 或者 Method ,或者在调用 Object.wait 后重新进入同步块/方法.简单的说,就是线程等待 synchronized 形式的锁时的状态 下面这段代码中, t1 在等待

  • 浅谈java线程状态与线程安全解析

    目录 1.线程的几种状态 1.1 线程的状态 1.2 线程状态的转移 2.有关线程安全问题 2.1 一个简单的例子 2.2 造成线程不安全的原因 1.线程的几种状态 1.1 线程的状态 以下就是我们线程所有的状态和意义: NEW 已经创建Thread但未创建线程 RUNNABLE 可工作的. 又可以分成正在工作中和即将开始工作 BLOCKED 等待锁(阻塞状态) WAITING 调用wati方法(阻塞状态) TIMED_WAITING 调用sleep方法(阻塞状态) TERMINATED 系统线

  • 浅谈Java线程间通信之wait/notify

    Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.先来我们来看下相关定义: wait() :调用该方法的线程进入WATTING状态,只有等待另外线程的通知或中断才会返回,调用wait()方法后,会释放对象的锁. wait(long):超时等待最多long毫秒,如果没有通知就超时返回. notify() :通知一个在对象上等待的线程,使其从wait()方法返回,而返回的前提

  • 浅谈java线程中生产者与消费者的问题

    一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费者必须停止消费,直到仓库中有产品. 解决生产者/消费者问题主要用到如下几个技术:1.用线程模拟生产者,在run方法中不断地往仓库中存放产品.2.用线程模拟消费者,在run方法中不断地从仓库中获取产品.3  . 仓库类保存产品,当产品数量为0时,调用wait方法,使得当前消费者线程进入等待状态,当有新

  • 浅谈Java线程池是如何运行的

    异步编程工具在Android开发中目前最被推荐的就是Kotlin协程,在引入Kotlin协程机制前,除了响应式扩展(RxJava)兼任异步编程工具外,Java API中线程与线程池就是最重要异步编程手段.而对于Android平台的Kotlin协程实现来说,依然使用的是线程池来作为任务执行的载体,所以可以将Android平台的Kotlin协程简单的理解是对线程池的一种高度封装. Executors.newFixedThreadPool(10).asCoroutineDispatcher() Dis

  • 浅谈Java线程池的7大核心参数

    前言 java中经常需要用到多线程来处理一些业务,我不建议单纯使用继承Thread或者实现Runnable接口的方式来创建线程,那样势必有创建及销毁线程耗费资源.线程上下文切换问题. 同时创建过多的线程也可能引发资源耗尽的风险,这个时候引入线程池比较合理,方便线程任务的管理. java中涉及到线程池的相关类均在jdk1.5开始的java.util.concurrent包中,涉及到的几个核心类及接口包括: Executor.Executors.ExecutorService.ThreadPoolE

  • 浅谈Java线程Thread.join方法解析

    join字面上是加入的意思,我们先看看join方法的解释和实现. /** * Waits for this thread to die. * 调用方线程(调用join方法的线程)执行等待操作,直到被调用的线程(join方法所属的线程)结束,再被唤醒 * <p> An invocation of this method behaves in exactly the same * way as the invocation * * * @throws InterruptedException *

随机推荐