`
h140465
  • 浏览: 21813 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java多线程之join

阅读更多

    join是线程的一个方法,在API中,它的英文解释是Waits for this thread to die.等待此线程死亡。谁等待此线程死亡呢?不难看出,这过程中至少存在两个线程,一个调用线程的线程,一个被调用的线程。我们通过一个简单的示例来理解这句话。    

package com.doufu.thread.t01;

class ThreadA extends Thread{

	private String name;
	
	public ThreadA(String name){
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name);
	}
	
}
public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t = new ThreadA("T1");
		t.start();
		t.join();
		System.out.println("main");
	}
}

     在上面代码中,调用线程的线程是main即主线程,被调用的线程是t。t.join()的意思即等待t的死亡(运行结束),等待t运行结束的线程就是main。所以上面的代码执行结果应该是先打印T1,再打印main。    

    通过以上代码,可以理解,在A线程中调用另外一个线程B的join方法,即让线程A进入Block状态,直到线程B运行结束。下面再看一个示例:

     只贴出了修改的部分

public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t = new ThreadA("T1");
		t.join();
		t.start();
		System.out.println("main");
	}
}

   运行结果:

 

    

  看这输出结果,是不是觉得不对,不是好说了,在main中调用t的join方法,会让main先挂起,直到t执行结束吗,怎么先打印main了呢?我们来看下Thread类的join源码:

    

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

    join(),实际上是调用另外一个join(long millis)的方法,我们再来看下join(long millis)方法   

 

 

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()方法时,线程不是活着的,则无效。以下是isAlive()的源码,注意看下方法注释  

 

 

/**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */
    public final native boolean isAlive();

   我们来看一个面试题:     

写道
现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?

    此面试题,我们可以用join来实现   

class ThreadA extends Thread{

	private String name;
	
	public ThreadA(String name){
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name);
	}
	
}

class ThreadB extends Thread{

	private String name;
	private Thread thread;
	public ThreadB(String name,Thread thread){
		this.name = name;
		this.thread = thread;
	}
	
	@Override
	public void run() {
		try {
			thread.join();//让此线程进入Block
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println(name);
	}
}
public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t1 = new ThreadA("T1");
		ThreadB t2 = new ThreadB("T2",t1);
		ThreadB t3 = new ThreadB("T3",t2);
		
		t1.start();
		t2.start();
		t3.start();
	}
}

 运行结果:   


 

 以下更简单的实现方式:

public class JoinTest {
	
	static class JoinThread implements Runnable{
		private String name;

		public JoinThread(String name){
			this.name = name;
		}
		
		@Override
		public void run() {
			System.out.println(name);
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("结束"+name);
		}
		
	}

	public static void main(String[] args) throws Exception {
		
		for(int i=0;i<3;i++){
			Thread t = new Thread(new JoinThread("t"+i));
			t.start();
			t.join();
		}
	
		System.out.println("HAHAHA");
		
		
	}

	
}

 运行结果:


使用CountDownLatch实现

import java.util.concurrent.CountDownLatch;

public class CoutDownLatchTest {

	private static final CountDownLatch c1 = new CountDownLatch(1);
	
	private static final CountDownLatch c2 = new CountDownLatch(2);
	
	public static void main(String[] args) {
		
		Thread t1 = new Thread(){
			public void run(){
				System.out.println("结束"+1);
				c1.countDown();
				c2.countDown();
			}
		};
		
		Thread t2 = new Thread(){
			public void run(){
				try {
					c1.await();
					System.out.println("结束"+2);
					c2.countDown();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
		};
		
		Thread t3 = new Thread(){
			public void run(){
				try {
					c2.await();
					System.out.println("结束"+3);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
		};
		
		t3.start();
		t2.start();
		t1.start();
		System.out.println("HAHAHA");
	}

 

  • 大小: 10 KB
  • 大小: 6.8 KB
  • 大小: 6.6 KB
  • 大小: 7.2 KB
2
1
分享到:
评论

相关推荐

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    java多线程Demo

    Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...

    java多线程经典案例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...

    深入浅出 Java 多线程.pdf

    在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...

    Java多线程技术精讲

    Java多线程技术是Java编程中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多线程是实现并发处理的关键技术,尤其在服务器端应用和高性能计算中不可或缺。 ...

    Java多线程实现异步调用实例

    总之,Java多线程和异步调用是构建高效、响应迅速的应用程序的关键技术。通过合理利用这些工具和机制,开发者可以编写出能够充分利用多核处理器优势的代码,从而提高软件性能。在实际应用中,理解并熟练掌握这些概念...

    java 多线程示例

    Java多线程是Java编程中的重要概念,尤其在开发高性能、高并发的应用中不可或缺。本示例旨在为初学者提供一个全面理解Java多线程的起点。通过学习这个实例,你可以掌握如何创建和管理线程,理解线程同步与通信的重要...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。

    java多线程进阶

    Java多线程是Java编程中的核心概念,尤其对于高级开发者来说,掌握多线程的深入理解和应用至关重要。这本书“java多线程进阶”显然旨在帮助读者深化这方面的理解,打通编程中的“任督二脉”,使开发者能够更加熟练地...

    java 多线程.ppt,多线程

    Java多线程是Java编程中一个重要的概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要分为两种实现方式:通过子类化Thread类和实现Runnable接口。 1. 子类化Thread类: 当...

    Java多线程资料

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了软件的效率和响应性。在Java中,多线程的实现主要有两种方式:通过继承Thread类和实现Runnable接口。这篇资料深入探讨了Java多线程的相关知识...

    Java多线程下载

    Java多线程下载技术是Java开发中用于提升大文件下载效率的一种常见方法。在传统的单线程下载过程中,网络请求可能会因为各种原因中断,如网络波动、服务器问题或用户操作等,这会导致需要从头开始下载,浪费时间和...

    java多线程小汽车运行程序

    Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在这个名为"java多线程小汽车运行程序"的项目中,我们可以看到一个利用Java实现的多线程应用程序,可能是模拟汽车...

    Java多线程的总结

    Java多线程是Java编程中的一个核心概念,它在现代软件开发中扮演着至关重要的角色。多线程允许程序同时执行多个任务,提高了系统资源的利用率,提升了应用程序的响应速度和并发性能。对于大型分布式系统、Web应用...

    java 多线程编程指南

    这份“Java多线程编程指南”深入探讨了这一主题,为中级到高级的Java开发者提供了宝贵的资源。 首先,多线程的基础概念是理解整个主题的关键。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、...

    java多线程并发实战和源码

    Java多线程并发实战与源码分析是Java开发中至关重要的一部分,它涉及到程序性能优化、系统资源高效利用以及复杂逻辑的正确同步。本书主要聚焦于Java多线程的基础理论和实际应用,虽然书中实例和源码相对较少,但仍然...

    JAVA多线程模式高清版+DEMO

    Java多线程是Java编程中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过继承`Thread`类或者实现`Runnable`接口。这个压缩包文件"JAVA多...

    JAVA多线程(精典总结)

    Java多线程是Java编程中不可或缺的部分,尤其在面试中,多线程的知识点经常被问及。本文将深入探讨Java多线程的核心概念、创建方式、线程状态转换、线程调度以及线程优先级调整。 首先,理解线程的基本概念至关重要...

Global site tag (gtag.js) - Google Analytics