JAVA多线程之方法 JOIN详解及实例代码

 更新时间:2017年02月15日 08:40:48   投稿:lqh  
这篇文章主要介绍了JAVA多线程之方法 JOIN详解及实例代码的相关资料,需要的朋友可以参考下

JAVA多线程 JOIN

 对于Java开发人员,多线程应该是必须熟练应用的知识点,特别是开发基于Java语言的产品。本文将深入浅出的表述Java多线程的知识点,在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用。

    如何才能深入浅出呢,我的理解是带着问题,而不是泛泛的看。所以该系列基本以解决问题为主,当然我也非常希望读者能够提出更好的解决问题的方案以及提出更多的问题。由于水平有限,如果有什么错误之处,请大家提出,共同讨论,总之,我希望通过该系列我们能够深入理解Java多线程来解决我们实际开发的问题。

    作为开发人员,我想没有必要讨论多线程的基础知识,比如什么是线程? 如何创建等 ,这些知识点是可以通过书本和Google获得的。本系列主要是如何理深入解多线程来帮助我们平时的开发,比如线程池如何实现? 如何应用锁等。 

(1)方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答。
    自从接触Java多线程,一直对Join理解不了。JDK是这样说的:

  join
  public final void join(long millis)throws InterruptedException
  Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

 大家能理解吗? 字面意思是等待一段时间直到这个线程死亡,我的疑问是那个线程,是它本身的线程还是调用它的线程的,上代码:

package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    t.start();
    try {
      t.join(1000);
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(1000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }
}

结果是:

Begin sleep
End sleep
joinFinish

明白了吧,当main线程调用t.join时,main线程等待t线程,等待时间是1000,如果t线程Sleep 2000呢 

 public void run() {
    try {
      System.out.println("Begin sleep");
      // Thread.sleep(1000);
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

结果是:

Begin sleep
joinFinish
End sleep

也就是说main线程只等1000毫秒,不管T什么时候结束,如果是t.join()呢, 看代码:  

public final void join() throws InterruptedException {
  join(0);
  }

就是说如果是t.join() = t.join(0) 0 JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远等待,是这样吗?
其实是等到t结束后。

这个是怎么实现的吗? 看JDK代码:

 /**
   * Waits at most <code>millis</code> milliseconds for this thread to 
   * die. A timeout of <code>0</code> means to wait forever. 
   *
   * @param   millis  the time to wait in milliseconds.
   * @exception 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 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;
    }
  }
  }

其实Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。

这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t.join(1000)不是说明了main线程等待1秒,如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1毫秒了。上代码介绍:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    new ThreadTest(t).start();
    t.start();
    try {
      t.join();
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class ThreadTest extends Thread {

  Thread thread;

  public ThreadTest(Thread thread) {
    this.thread = thread;
  }

  @Override
  public void run() {
    holdThreadLock();
  }

  public void holdThreadLock() {
    synchronized (thread) {
      System.out.println("getObjectLock");
      try {
        Thread.sleep(9000);

      } catch (InterruptedException ex) {
       ex.printStackTrace();
      }
      System.out.println("ReleaseObjectLock");
    }

  }
}

class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }


  }
}

在main方法中 通过new ThreadTest(t).start();实例化ThreadTest 线程对象, 它在holdThreadLock()方法中,通过synchronized (thread),获取线程对象t的锁,并Sleep(9000)后释放,这就意味着,即使main方法t.join(1000),等待一秒钟,它必须等待ThreadTest 线程释放t锁后才能进入wait方法中,它实际等待时间是9000+1000 MS

运行结果是:

getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish

小结:

本节主要深入浅出join及JDK中的实现。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • 浅谈Springboot之于Spring的优势

    浅谈Springboot之于Spring的优势

    这篇文章主要介绍了浅谈Springboot之于Spring的优势,简述了在Java EE开发中遇到的问题,言简意赅,需要的朋友可以参考下。
    2017-09-09
  • Servlet实现多文件上传功能

    Servlet实现多文件上传功能

    这篇文章主要为大家详细介绍了Servlet实现文件上传功能,还可以实现Servlet多文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Java基础篇之反射机制示例详解

    Java基础篇之反射机制示例详解

    反射是Java可以提供的一个灵活又强大的功能,使用Java反射,您可以知道这个类在运行时具有什么属性和方法,也可以修改属性,调用方法,创建类的实例,这篇文章主要给大家介绍了关于Java基础篇之反射机制的相关资料,需要的朋友可以参考下
    2021-11-11
  • Java DOM4J方式生成XML的方法

    Java DOM4J方式生成XML的方法

    今天小编就为大家分享一篇Java DOM4J方式生成XML的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • java ThreadPool线程池的使用,线程池工具类用法说明

    java ThreadPool线程池的使用,线程池工具类用法说明

    这篇文章主要介绍了java ThreadPool线程池的使用,线程池工具类用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Eclipse+Java+Swing实现斗地主游戏(代码)

    Eclipse+Java+Swing实现斗地主游戏(代码)

    这篇文章主要介绍了Eclipse+Java+Swing实现斗地主游戏并附上详细的代码实现,正在学习的你可以当小练习练练,希望对你有所帮助
    2022-01-01
  • 深度源码解析Java 线程池的实现原理

    深度源码解析Java 线程池的实现原理

    如何高效的使用这些资源就是程序员在平时写代码时候的一个努力的方向。本文要说的线程池就是一种对 CPU 利用的优化手段。对Java 线程池的实现原理相关知识感兴趣的朋友一起看看吧
    2021-05-05
  • Mybatis源码解析之初始化分析

    Mybatis源码解析之初始化分析

    这篇文章主要介绍了Mybatis源码解析之初始化分析,Mybatis的初始化过程就是mybatis配置文件的解析过程并将解析结果保存到Configuration类。,需要的朋友可以参考下
    2024-01-01
  • java 如何为文件及文件夹添加权限

    java 如何为文件及文件夹添加权限

    这篇文章主要介绍了java 如何为文件及文件夹添加权限的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java File类的详解及简单实例

    Java File类的详解及简单实例

    这篇文章主要介绍了Java File类的详解及简单实例的相关资料,希望通过本文大家能够掌握这部分内容,需要的朋友可以参考下
    2017-09-09

最新评论