《Java程序员面试秘笈》—— 1.7 等待线程的终止

1.7 等待线程的终止

在一些情形下,我们必须等待线程的终止。例如,我们的程序在执行其他的任务时,必须先初始化一些必须的资源。可以使用线程来完成这些初始化任务,等待线程终止,再执行程序的其他任务。

为了达到这个目的,我们使用Thread类的join()方法。当一个线程对象的join()方法被调用时,调用它的线程将被挂起,直到这个线程对象完成它的任务。

在本节中,我们将通过初始化资源的范例来学习join()方法。

准备工作
本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。

范例实现
按照接下来的步骤实现本节的范例。

1.创建名为DataSourcesLoader的类,并且实现Runnable接口。
``
public class DataSourcesLoader implements Runnable {``
2.实现run()方法。这个方法先显示一个表明它开始执行的信息,然后休眠4秒钟,再显示另一个信息表明已完成当前执行。

@Override
public void run() {
  System.out.printf("Beginning data sources loading: %s\n",new Date());
    try {
       TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
       e.printStackTrace();
    }
    System.out.printf("Data sources loading has finished: %s\n",new Date());
}```
3.创建一个NetworkConnectionsLoader类,用以实现Runnable接口。实现run()方法的方式与DataSourcesLoade的run()方法类似,但是它休眠6秒钟。

4.创建一个包含main()方法的Main类。

public class Main {
public static void main(String[] args) {`
5.创建一个DataSourcesLoader对象,并用它作为传入参数来创建一个线程。

DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader,"DataSourceThread");```
6.创建一个NetworkConnectionsLoader对象,并用它作为传入参数来创建一个线程。

NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");`
7.调用start()方法启动这两个线程对象。

thread1.start();
thread2.start();```
8.使用join()方法等待两个线程的终止。join()方法会抛出InterruptedException异常,我们必须捕获并处理这个异常。

try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}`
9.程序运行结束时,打印出信息。
``
System.out.printf("Main: Configuration has been loaded: %sn",new Date());``
10.运行程序并观察运行结果。

工作原理
运行这个程序时,你会看到两个线程对象是如何运行的。DataSourcesLoader线程运行结束,NetworkConnectionsLoader线程也运行结束的时候,主线程对象才会继续运行并且打印出最终的信息。

更多信息
Java提供了另外两种形式的join()方法:

join (long milliseconds)

join (long milliseconds, long nanos)

当一个线程调用其他某个线程的join()方法时,如果使用的是第一种join()方式,那么它不必等到被调用线程运行终止,如果参数指定的毫秒时钟已经到达,它将继续运行。例如,thread1中有这样的代码thread2.join(1000),thread1将挂起运行,直到满足下面两个条件之一:

◆ thread2运行已经完成;

◆ 时钟已经过去1000毫秒。

当两个条件中的任何一条成立时,join()方法将返回。

第二种join()方法跟第一种相似,只是需要接受毫秒和纳秒两个参数。

时间: 2024-12-26 04:08:21

《Java程序员面试秘笈》—— 1.7 等待线程的终止的相关文章

《Java程序员面试秘笈》—— 1.5 线程中断的控制

1.5 线程中断的控制 通过上一节,你已经学会了如何去中断执行中的线程,也学会了如何在线程对象中去控制这个中断.上一个例子中使用的机制,可以使用在线程很容易被中断的情况下.但是,如果线程实现了复杂的算法并且分布在几个方法中,或者线程里有递归调用的方法,我们就得使用一个更好的机制来控制线程的中断.为了达到这个目的,Java提供了InterruptedException异常.当检查到线程中断的时候,就抛出这个异常,然后在run()中捕获并处理这个异常. 在本节中,我们将实现线程类来完成下面的内容,它

《Java程序员面试秘笈》—— 1.2 线程的创建和运行

1.2 线程的创建和运行 在本章中,我们将学习如何在Java程序中创建和运行线程.在Java语言中,线程跟其他所有元素一样,都是对象(Object).Java提供了两种方式来创建线程: ◆ 继承Thread类,并且覆盖run()方法. ◆ 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象.这个参数就是实现Runnable接口的类的一个对象. 在本章中,我们将使用第二种方法创建一个简单的程序,这个程序将创建并运行10个线程.每个线程用以计算和打印乘以1-1

《Java程序员面试秘笈》—— 1.4 线程的中断

1.4 线程的中断 如果一个Java程序有不止一个执行线程,当所有线程都运行结束的时候,这个Java程序才能运行结束:更确切地说应该是所有的非守护线程运行结束时,或者其中一个线程调用了System.exit()方法时,这个Java程序才运行结束.如果你想终止一个程序,或者程序的某个用户试图取消线程对象正在运行的任务,就需要结束这个线程. Java提供了中断机制,我们可以使用它来结束一个线程.这种机制要求线程检查它是否被中断了,然后决定是不是响应这个中断请求.线程允许忽略中断请求并且继续执行. 在

《Java程序员面试秘笈》—— 1.9 线程中不可控异常的处理

1.9 线程中不可控异常的处理 在Java中有两种异常. ◆ 非运行时异常(Checked Exception):这种异常必须在方法声明的throws语句指定,或者在方法体内捕获.例如:IOException和ClassNotFoundException. ◆ 运行时异常(Unchecked Exception):这种异常不必在方法声明中指定,也不需要在方法体中捕获.例如:NumberFormatException. 因为run()方法不支持throws语句,所以当线程对象的run()方法抛出非

《Java程序员面试秘笈》—— 1.10 线程局部变量的使用

1.10 线程局部变量的使用 共享数据是并发程序最核心的问题之一,对于继承了Thread类或者实现了Runnable接口的对象来说尤其重要. 如果创建的对象是实现了Runnable接口的类的实例,用它作为传入参数创建多个线程对象并启动这些线程,那么所有的线程将共享相同的属性.也就是说,如果你在一个线程中改变了一个属性,所有线程都会被这个改变影响. 在某种情况下,这个对象的属性不需要被所有线程共享.Java并发API提供了一个干净的机制,即线程局部变量(Thread-Local Variable)

《Java程序员面试秘笈》—— 1.3 线程信息的获取和设置

1.3 线程信息的获取和设置 Thread类有一些保存信息的属性,这些属性可以用来标识线程,显示线程的状态或者控制线程的优先级. ID:保存了线程的唯一标示符. Name:保存了线程名称 Priority:保存了线程对象的优先级.线程的优先级是从1到10,其中1是最低优先级:10是最高优先级.我们并不推荐去改变线程的优先级,然而,在需要的时候,也可以这么做. Status:保存了线程的状态.在Java中,线程的状态有6种:new.runnable.blocked.waiting.time wai

《Java程序员面试秘笈》—— 1.12 线程组中不可控异常的处理

1.12 线程组中不可控异常的处理 提供应用程序中对错误情景的管理,是编程语言很重要的一面.和几乎所有的现代编程语言一样,Java语言也实现了通过异常管理机制来处理错误情景,它提供了很多类来表示不同的错误.当错误情景发生时,Java类将抛出这些异常.你可以使用这些异常,或者实现自己的异常,来管理类中的错误. Java也提供了捕获和处理这些异常的机制.有的异常必须被捕获,或者必须使用方法的throws声明再次抛出,这类异常叫做非运行时异常.还有一类异常叫做运行时异常,它们不需要被捕获或者声明抛出.

《Java程序员面试秘笈》—— 1.11 线程的分组

1.11 线程的分组 Java并发API提供了一个有趣的功能,它能够把线程分组.这允许我们把一个组的线程当成一个单一的单元,对组内线程对象进行访问并操作它们.例如,对于一些执行同样任务的线程,你想控制它们,不管多少线程在运行,只需要一个单一的调用,所有这些线程的运行都会被中断. Java提供ThreadGroup类表示一组线程.线程组可以包含线程对象,也可以包含其他的线程组对象,它是一个树形结构. 在本节中,我们学习并使用ThreadGroup对象类开发一个简单的范例:创建10个线程并让它们休眠

《Java程序员面试秘笈》—— 面试题11 使用jar命令

面试题11 使用jar命令 Java程序员面试秘笈 请使用jar命令,将test文件夹压缩成.jar文件,并简述其压缩包的结构. 考点:对于Java程序员来说,更多情况下是使用的集成Java开发工具,例如JBuilder.Eclipse等,而对于最基本的Java编译和常见的命令行工具往往都不熟悉.这个面试题主要考察求职者对于Java命令行基本工具的使用,从而了解求职者对Java编程的熟悉程度. 出现频率: [面试题解析]熟练的Java开发者应该掌握常用的Java命令行工具.求职者应该熟练掌握ja

《Java程序员面试秘笈》—— 面试题12 如何执行mian()方法

面试题12 如何执行mian()方法 Java程序员面试秘笈 利用Java SDK中哪一条命令能够执行test的main()方法? (a)java test (b)javac test (c)java test.java (d)java test.class (e)java test.main 考点:考察求职者对java命令的熟悉程度. 出现频率: [面试题解析]求职者容易出现的错误是选择了(d).实际上,java命令后面只需要class文件的名称就可以,不用加入.class全名.如果使用jav