`
king_tt
  • 浏览: 2110892 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java中的线程Thread方法之---join()

 
阅读更多

上一篇我们说到了Thread中的stop方法,这一篇我们再来看一下方法join的使用,那么方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答。


join方法从字面上的意思就是加入到一个线程中,这样就可以很好的进行线程之间的交互运行了,不多说先来看一下代码:

package com.threadjoin.demo;

public class ThreadJoin {
	
	public static int a = 0;
	
	public static void main(String[] args){
		Thread thread = new Thread(new Runnable(){
			@Override
			public void run(){
				for(int i=0;i<5;i++)
					a++;
			}
		});
		thread.start();
		/*try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		System.out.println(a);
		
	}
	
}

运行代码,貌似永远都看不到a的值是5,而每次都是0,原因很简单的,因为在thread中的run方法中进行a的增值操作,这些可能都是需要时间的,但是此时main线程中的System.out.println方法已经执行了,所以很难看到a的值是5,为了看到a的值是5,我的一个思路就是等thread运行结束之后,我们采取执行System.out.println就可以了,这时候join方法的作用就显现出来的,我们把上面的注释代码删除注释,然后运行,不管运行多少次,输出的结果都是5,从这个例子中我们就可以看到join方法的作用,它能够调节各个线程之间的运行顺序,从而可以实现同步。为了更好的了解join的运行原理我们只有看他的源码了:

  1. publicfinalvoidjoin()throwsInterruptedException{
  2. join(0);
  3. }
我们在跟踪到join(0)方法中:

  1. //方法是个同步的,而且会抛出InterruptedException异常
  2. publicfinalsynchronizedvoidjoin(longmillis)throwsInterruptedException{
  3. longbase=System.currentTimeMillis();
  4. longnow=0;
  5. if(millis<0){
  6. thrownewIllegalArgumentException("timeoutvalueisnegative");
  7. }
  8. //我们可以看到这里使用了while循环做判断的,然后调用wait方法的,所以说join方法的执行是完全通过wait方法实现的
  9. //等待时间为0的时候,就是无限等待,直到线程死亡了(即线程执行完了)
  10. if(millis==0){
  11. //如果当前线程还存活的话,就等待
  12. while(isAlive()){
  13. //调用该线程的join方法的线程拿到锁之后进行等待,直到线程执行结束(这个例子就是main线程)
  14. wait(0);
  15. }
  16. }else{
  17. //如果是等待的特定时间的话
  18. while(isAlive()){
  19. longdelay=millis-now;
  20. if(delay<=0){
  21. break;
  22. }
  23. wait(delay);
  24. now=System.currentTimeMillis()-base;
  25. }
  26. }
  27. }
从代码中我们可以看到join方法是个同步的,这个我们后面会做个例子,然后进入到方法中我们可以看到,有两种情况,一种是等待时间是0的,其实就等同无线等待,直到线程执行结束了,还有一种就是要等待的是一定的时间,原理都是一样的,


看完源码之后我们在看一一个例子:

  1. packagecom.threadjoin.demo;
  2. /**
  3. *
  4. 其实Join方法实现是通过wait(小提示:Object提供的方法)。
  5. 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait意味着拿到该对象的锁),
  6. 调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。
  7. 这就意味着main线程调用t.join时,
  8. 必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t.join(1000)不是说明了main线程等待1秒,
  9. 如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1秒了
  10. *@authorweijiang204321
  11. *
  12. */
  13. publicclassThreadJoinTest{
  14. publicstaticvoidmain(String[]args){
  15. Threadt=newThread(newRunnableImpl());
  16. newThreadTest(t).start();
  17. t.start();
  18. try{
  19. t.join(1000);
  20. System.out.println("joinFinish");
  21. }catch(InterruptedExceptione){
  22. e.printStackTrace();
  23. }
  24. }
  25. }
  26. classRunnableImplimplementsRunnable{
  27. @Override
  28. publicvoidrun(){
  29. try{
  30. System.out.println("Beginsleep");
  31. Thread.sleep(1000);
  32. System.out.println("Endsleep");
  33. }catch(InterruptedExceptione){
  34. e.printStackTrace();
  35. }
  36. }
  37. }
  38. classThreadTestextendsThread{
  39. Threadthread;
  40. publicThreadTest(Threadthread){
  41. this.thread=thread;
  42. }
  43. @Override
  44. publicvoidrun(){
  45. holdThreadLock();
  46. }
  47. publicvoidholdThreadLock(){
  48. //用当前的线程当做lock
  49. synchronized(thread){
  50. System.out.println("getObjectLock");
  51. try{
  52. Thread.sleep(9*1000);
  53. }catch(InterruptedExceptionex){
  54. ex.printStackTrace();
  55. }
  56. System.out.println("ReleaseObjectLock");
  57. }
  58. }
  59. }
在main方法中通过newThreadTest(t).start()实例化ThreadTest线程对象, 它通过synchronized(thread),获取线程对象t的锁,并sleep(9*1000)后释放,因为我们上面看到了join方法是个同步的,而且同步锁是当前的线程对象,因为ThreadTest先运行的,首先拿到了线程t对象的锁,所以join方法还没有拿到锁,所以要等待。这就意味着,即使main方法t.join(1000)等待一秒钟,它必须等待ThreadTest线程释放t锁后才能进入wait方法中,它实际等待时间是9000+1000ms=10s。
分享到:
评论

相关推荐

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

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

    Java线程之join_动力节点Java学院整理

    join() 定义在Thread.java中。 join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。这句话可能有点晦涩,我们还是通过例子去理解

    线程的基本概念、线程类、任务类、线程优先级、sleep()方法、yield()方法、join方法、interrupt()方法

    线程的基本概念、线程类...在Java中,可以使用Thread类的join()方法实现线程的合并。 线程的中断是指在一个线程中断另一个线程的执行。在Java中,可以使用Thread类的interrupt()方法实现线程的中断。(run方法执行完毕)

    java线程分析java project例子

    java线程分析java project例子,里面分析了sleep(),join(),yield()和wait以及notify等方法的使用以及需要注意的地方。

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

    通过sleep可以使线程进入休眠状态,通过join方法可以让线程处于等待,其他线程执行完毕后继续执行。 线程生命周期包括:新建 就绪 运行 阻塞 死亡5种状态。 Java高级程序设计-多线程(二)全文共34页,当前为第2页。 ...

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

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

    什么是线程?Java中如何创建和管理线程?(java面试题附答案).txt

    通过将 MyRunnable 对象传递给 Thread 类的构造方法,我们创建了一个新的线程,并将 run 方法作为线程的执行逻辑。 除了基本的线程创建和启动,Java还提供了一些管理线程的方法和工具,例如: sleep 方法:使当前...

    java多线程Thread的实现方法代码详解

    主要介绍了java多线程Thread的实现方法代码详解,涉及start(),run(),stop(),interrupt(),isInterrupted(),join()和join(long millis)等方法的介绍,具有一定借鉴价值,需要的朋友可以了解下。

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

    本篇文章主要介绍了浅谈Java线程Thread.join方法解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    多线程机制

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

    线程学习小Test

    Java线程 wait notify sleep join 同步实现Demo

    JAVA多线程技术分享-39页PPT(winding)

    分享的多线程技术不是告诉你什么是线程,线程的状态,而是我们在开发中容易踩的坑,受过的伤害。我不会告诉你什么是爱情,但是我会告诉你爱过。 一 基础: 1,Thread.sleep(0)的作用 2,为什么线程会带来性能问题 3...

    Java实验指导书_多线程

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

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

    下载部分的内容是通过创建一个DownloadThread子类来实现的,该子类继承自Thread类,重写了run()方法,在该方法中读取URL对应流的数据,并将数据写入到指定的输出流中。最后,通过调用每个线程的join()方法等待所有...

    Java线程

    目录 理解线程的概念 ... 在Java中,每次程序运行至少启动2个线程:一个是main线程,一个是垃圾收gc集线程。每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM实际上就是在操作系统中启

    Java多线程详解

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

    java高并发相关知识点.docx

    线程安全:Java中的线程安全,包括同步方法和同步块等。 死锁:Java中的死锁,包括如何避免死锁和如何解除死锁。 性能优化:Java中的性能优化,包括JVM参数调优、代码优化、使用并发框架等。 并行计算:Java中的并行...

    Java开发技术大全(500个源代码).

    invokeMethod.java 同一个类中调用方法示例 invokeOther.java 类的外部调用方法示例 invokeStaticMethod.java 调用静态方法示例 localVariable.java 演示局部变量 localVSmember.java 局部变量与成员变量同名...

    java7源码-thread:多线程相关的学习

    Java多线程 [TOC] 线程状态 1.New:尚未启动的线程的线程状态 2.Runnable:可运行线程的线程状态,等待CPU调度 3.Blocked:线程阻塞等待监视器锁定的线程状态 4.Waiting:等待线程的线程状态(wait、join、park) 5....

    Java 多线程技术:(四)获取线程基本信息_暂停线程_线程的优先级_多线程的安全性_线程同步

    暂停线程执行 sleep_yield_join_stop3.线程的优先级问题4.多线程的安全性问题5.线程同步1.同步代码块2.同步方法 1.线程操作的常用方法 序号 方法名称 描述 1 static Thread currentThread() 返回目前正在执行...

Global site tag (gtag.js) - Google Analytics