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 ...
随机推荐
- 9 HTML&JS等前端知识系列之Ajax post请求带有token向Django请求
我们 在母板上写入这段代码: <script type="text/javascript"> // 个人定义大函数,不是重点,可以忽略 $(document).read ...
- 适可而止:YAGNI原则
适可而止:You Ain't Gonna Need It YAGNI原则指的是只需要将应用程序必需的功能包含进来,而不要试图添加任何其他你认为可能需要的功能. 在一个软件项目中,往往80%的时间花费在 ...
- 过滤字符串的Html标记 c#函数 .
.public static string StripHTML(string strHtml) . { . string[] aryReg ={ . @"<script[^>]* ...
- Linux服务器间文件传输
利用scp传输文件 1.从服务器下载文件 scp username@servername:/path/filename /tmp/local_destination 例如scp codinglog@1 ...
- Spring MVC学习笔记——POJO和DispatcherServlet
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称. 使用POJO名称是为了避免和EJB(Enter ...
- C#中操作XML文件
1.添加结点:XmlNode xmldoc.Load("..\\..\\App.config"); //根元素 XmlElement root = xmldoc.DocumentE ...
- RHEL-界面中文乱码问题
一.虚拟机里的rhel更换为中文简体后,中文字符变为小方块 二.解决方法: 安装中文支持的软件包 fonts-chinese-3.02-12.el5.noarch.rpm fonts-ISO8859- ...
- 常用JS效果 不断进步贴 不停更新~ 纪念用~
常用效果 JS 都是Jquery 没有特殊说明 1.选项卡 用的JQuery 以后学好点再来对比 看下 /* * @parent 最外层父级元素 * @EventElement 触发事件元素 ...
- OC-Q&A
How to declare a string in Objective-C ? A C string is just like in C. char myCString[] = "test ...
- 浅谈T-SQL中的联接查询
引言 平时开发时,经常会使用数据库进行增删改查,免不了会涉及多表联接.今天就简单的记录下T-SQL下的联接操作. 联接类型及其介绍 在T-SQL中联接操作使用的是JOIN表运算符.联接有三种基本的类型 ...