Java 7 Concurrency Cookbook 翻译 第一章 线程管理之三
五、睡眠和唤醒一个线程
有时,你会想要在一段特定的时间后再去中断线程的运行。举个例子,程序中的一个线程每一分钟检查一次传感器的状态,剩余的时间,线程应该处于空闲的状态。在这段空闲时间里,线程不会使用计算机的任何资源。一分钟后,线程已经准备好了,才让JVM选择调用它继续执行。你可以使用 Thread 类的 sleep() 方法来达到此目的。该方法接受一个 int 类型参数表明线程挂起不运行的毫秒数。当睡眠时间结束,线程转移到可运行状态等待JVM的调度。
TimeUnit 枚举类的某个成员同样具有 sleep() 方法。该方法利用了 Thread 类的 sleep() 方法,使得当前线程睡眠,但是它接受的参数的单位并不是固定为毫秒数,更加方便。
在本秘诀中,我们开发一个利用 sleep() 方法每秒输出 Date 值的程序。
public class FileMain {
public static void main(String[] args) {
FileClock clock = new FileClock();
Thread thread = new Thread(clock);
thread.start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
public class FileClock implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.printf("%s\n", new Date());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.printf("The FileClock has been interrupted");
}
}
}
}
当你调用 sleep() 方法时,线程就会放弃占用CPU和停止执行一段时间。在这段时间里,它不占用CPU时间。
当线程在睡眠中并且被中断时,该方法立即抛出一个 InterruptedException 异常,并不会等待直到睡眠时间到达。
注意:yield() 方法也具有让线程放弃占用CPU的功能,不过,这个方法最好只用来表明自己可以放弃CPU占用,JVM的规范中没有强制要求其必须要放弃CPU占用。这个方法一般只用在调试环境中,让具有更高权限的线程可以抢占执行。
笔者总结:线程调用 sleep() 方法后,该线程处于挂起状态,自身不会去抢占CUP等资源来运行,但JVM内部有系统线程去感知是否该睡眠线程被中断,从而以抛出异常方式通知睡眠线程提前唤醒来运行代码处理此种情况。
六、等待线程的完成
某些场景下,我们可能需要等待线程的终结。举个例子:我们的程序在顺序上可能需要在执行某些步骤之前需要初始化某些资源。我们可以把初始化资源的任务作为一个单独的线程运行,并且在主任务线程中等待它完成后再进行下一步的处理。
我们可以使用 Thread 类的 join() 方法达到该目的。当我们调用一个 Thread 对象的 join() 方法时,调用此方法的线程就会挂起,直到 Thread 对象关联的线程执行完毕。
public class DataSourcesLoader implements Runnable{
@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());
}
}
public class Main {
public static void main(String[] args) {
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourceThread");
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionLoader");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
}
}
public class NetworkConnectionsLoader implements Runnable{
@Override
public void run() {
System.out.printf("Beginning Network connection: %s\n",
new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Network connection has finished: %s\n",
new Date());
}
}
如果你运行此示例程序多次后就会发现,每次都是先运行 thread1 并结束后,才运行 thread2,thread2结束后才会结束 main 线程的运行。
join() 方法具有两个类似的方法,他们分别是:
(A) join(long milliseconds)
(B) join(long milliseconds, long nanos)
这两个方法通向会挂起调用线程直到该方法所属的 Thread 对象关联的线程执行结束,但是在指定的时间达到后,调用线程可以继续运行,不用一直等待。
笔者总结:这三个方法经常用来线程之间的同步,带参数的方法可以实现超时不等待逻辑。
重要:本系列翻译文档也会在本人的微信公众号(此山是我开)第一时间发布,欢迎大家关注。
Java 7 Concurrency Cookbook 翻译 第一章 线程管理之三的更多相关文章
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之一
一.简介 在计算机的世界里,当我们谈论并发时,我们指的是一系列的任务同时运行于一个计算机中.这里说的同时运行,在计算机拥有多于一个处理器或者是一个多核处理器的时候才是真正的同时,在计算机只拥有单核处理 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之六
十一.处理线程组中的未控制异常 每种编程语言一个很重要的特性就是其所提供的用来处理程序中错误情况的机制.Java语言和其他的现代语言一样,是提供了异常机制来处理对象程序中的错误.Java提供了很多的类 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之五
九.使用线程本地变量 一个并发程序的最关键特征就是共享数据.这个特性在那些继承了 Thread 类或者 实现了 Runnable 接口的对象上显得更加重要. 如果你创建一个实现了 Runnable 接 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四
七.创建和运行一个后台线程 Java中有一种特别的线程叫做 deamon(后台) 线程.这类线程具有非常低的权限,并且只有在同一个程序中没有其他的正常线程在运行时才会运行.注意:当一个程序中只剩下后台 ...
- Java 7 Concurrency Cookbook 翻译 第一章 线程管理之二
三.中断一个线程 一个拥有多个线程的Java程序要结束,需要满足两个条件之一:一是所有的非后台线程都执行结束了:二是某个线程执行了 System.exit() 方法.当你想要终结一个运行中的Java程 ...
- Java 7 Concurrency Cookbook 翻译 序言
在日常的Java代码开发过程中,很难免地有对多线程的需求,掌握java多线程和并发的机制也是Java程序员写出更健壮和高效代码的基础.笔者找寻国内已出版的关于Java多线程和并发的的中文书籍和翻译书籍 ...
- java的优点和误解 《java核心技术卷i》第一章
<java核心技术卷i>第一章主要内容包括三点: 1:Java白皮书的关键术语:描述Java的十一个关键字: 2:Java applet 3 :关于Java的常见误解 1:第一章:Ja ...
- java JDK8 学习笔记——第11章 线程和并行API
第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...
- Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记
第一章 Thread导论 为何要用Thread ? 非堵塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...
随机推荐
- JAVA内存机制
Java程序运行时,数据会分区存放,JavaStack(Java栈). heap(堆).method(方法区). 一.JVM内存模型 1.Java栈Java栈的区域很小,只有1M,特点是存取速度很快, ...
- 利用WireShark进行DNS协议分析
一.准备工作 系统是Windows 8.1Pro 分析工具是WireShark1.10.8 Stable Version 使用系统Ping命令发送ICMP报文. 二.开始工作 打开CMD.exe键入: ...
- 模拟退火解决TSP问题
// monituihuo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdio.h> #includ ...
- putty配色方案
最近用腻了putty默认的配色方案,所以打算换一下配色. 使用的是修改注册表的方法. 1.打开注册表:运行——>regedit 2.找到对应的注册表文件,并导出:注册表地址 HKEY_CURRE ...
- Android学习笔记——xml
转自http://blog.csdn.net/sam_zhang1984 解析 XML 有两种方式: SAX 和 DOM .它们各有利弊. DOM 是把 XML 文档全部装载到内存中,然后当成一树进行 ...
- Java VM for IOS
http://oss.readytalk.com/avian/ http://robovm.com/ http://www.xmlvm.org/overview/
- Which hashing algorithm is best for uniqueness and speed?
http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness- ...
- 扩展服务 修改新增Service的默认主题
问题描述:想要在F:\PHPnow-1.5.6\htdocs\yt\Yourphp\Tpl\ 目录下新增一个Service\Default(A) 和Service\new(B) 两个主题 ...
- Vim以及Terminal 配色方案---"Solarized"配色
linux用户给vim 以及terminal的配色方案---Solarized配色 官网地址:http://ethanschoonover.com/solarized 看这配色:八卦乾坤,赏心悦目,高 ...
- 使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句
开始 EF6.1也出来不少日子了,6.1相比6.0有个很大的特点就是新增了System.Data.Entity.Infrastructure.Interception 命名空间,此命名空间下的对象可以 ...