`

Java 多线程之Join

 
阅读更多

   方法Join 是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答。

   自从接触Java 多线程,一直对Join 理解不了。JDK 是这样说的:join public final void joinlong millisthrows 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) ; //
主线程只等1 秒,不管子线程什么时候结束
            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)  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 的锁,并Sleep9000 )后释放,这就意味着,即使
main
方法t.join(1000), 等待一秒钟,它必须等待
ThreadTest   线程释放t 锁后才能进入wait 方法中,它实际等待时间是9000+1000 MS
运行结果是:
getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish

分享到:
评论

相关推荐

    JAVA多线程编程详解-详细操作例子

    本压缩包,总共包含两个文档,JAVA多线程编程详解-详细操作例子和 Java多线 程编程总结 例如,runnable、thread、stop()、 suspend、yield、setPriority()、getPriority()、synchronized、wait()、join、线程池同步...

    Java线程中wait,await,sleep,yield,join用法总结.pdf

    Java线程中wait、await、sleep、yield、join用法汇总,文章里面总结了这些关键字的用法,并且里面带有源码帮助分析用法,此一文就可以理解这些关键字用法,推荐拥有

    【IT十八掌徐培成】Java基础第08天-02.多线程-join-daemon-同步.zip

    【IT十八掌徐培成】Java基础第08天-02.多线程-join-daemon-同步.zip

    Java学习源码Java多线程的代码

    在char01包里放置Java多线程基本知识的代码。内容如下: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 在char02包里放置了Java对变量和对象并发访问的知识的代码...

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

    主要介绍了JAVA多线程之方法 JOIN详解及实例代码的相关资料,需要的朋友可以参考下

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

    下面小编就为大家带来一篇浅谈java多线程 join方法以及优先级方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    个人总结的深入java多线程开发

    看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一. 线程池 1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 3)使用线程池的风险: 4 4)有效使用线程池的原则 5...

    java Fork Join框架及使用

    java Fork Join框架及使用,java自带的多线程框架,来处理多线程的问题

    java基本教程之join方法详解 java多线程教程

    本文对java Thread中join()方法进行介绍,join()的作用是让“主线程”等待“子线程”结束之后才能继续运行,大家参考使用吧

    Java多线程教程吐血整理干货.md

    多线程 进程和线程 并发和并行 多线程的利弊 什么是上下文切换? 线程的优先级 线程的几种状态 sleep方法和wait方法的区别 stop,suspend,resume等方法为什么会被遗弃 interrupt,interrupted,isInterrupted方法区别 ...

    多线程机制

    7、 浅析 Java Thread.join() : java多线程实现主线程等待所有子线程执行完毕 16 8、 线程运行中抛出异常的处理 19 9、 Callable 有返回值的线程 20 10、 Callable结合FutureTask的多线程使用(免打扰模式) 24

    Java多线程join方法实例代码

    主要介绍了Java多线程join方法实例代码,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    Java实验指导书_多线程

    Java实验指导书_多线程 《Java语言程序设计基础教程》 上机实验指导手册 异常处理 【目的】 ①线程的创建和运行 ②Thread类的sleep、join等方法的使用 ③线程同步

    多线程实验_1

    C#多线程实验,就AutoResetEvent,ManualResetEvent,Thread.join(),委托多线程回调。

    Java多线程详解

    文章目录1、进程与线程2、创建多线程2.1、继承Thread类2.2、实现Runnable接口2.3、使用匿名内部类实现2.4、实现Runnable接口的好处2.5、使用Callable和Future创建线程3、线程的生命周期4、几种特殊线程4.1、join线程...

    使用Java多线程实现下载多个文件.txt

    这段代码实现了一个下载器,可以同时下载多个文件。其中,构造函数MultiThreadDownloader接收一个URL数组和两个整数数组作为参数,分别表示每个URL的起始...最后,通过调用每个线程的join()方法等待所有线程执行完毕。

    Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐。虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用。之前,我讨论了一个wait...

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

    本文通过实例代码给大家实例介绍了Java多线程中关于join方法的使用,非常不错,具有参考借鉴价值,需要的朋友参考下

    Java高级程序设计-多线程(二).pptx

    第3章 多线程(二) Java 高级程序设计 Java高级程序设计-多线程(二)全文共34页,当前为第1页。 回顾 进程一般代表一个应用程序,一个进程中可以包含多个线程。 合理使用多线程能够提高程序的执行效率,处理高并发...

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

    join方法的功能就是使异步执行的线程变成同步执行。也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用join方法

Global site tag (gtag.js) - Google Analytics