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 ...
随机推荐
- oracle--知识点汇总1
同义词: -- e是scott.emp表的临时别名 select e.* from (select * from scott.emp) e; --创建私有同义词 create synonym myem ...
- uC/OS-II内核的服务文件
/*************************************************************************************************** ...
- logback 详解
原创文章,转载请指明出处:http://aub.iteye.com/blog/1103685, 尊重他人即尊重自己 详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透 ...
- 日志分析 第七章 安装grafana
grafana依赖mysql存储数据,首先需要安装mysql 安装mysql 解压 # groupadd mysql # useradd -s /sbin/nologin -g mysql mysql ...
- Cache-Aside Pattern解析
使用这种模式,可以帮助我们维护Cache中的数据. 使用Cache容易遇到的问题: 使用缓存,主要是为了将一些重复访问的数据存到缓存,开发者希望缓存中的数据和数据源中的保持一致,这就需要程序中有相应的 ...
- thinkphp 语言包丢失
Thinkphp 语言包丢失 造成的原因有那些 1.复制模板 预览时内容出现英文状态 如:show.html 解决:找到lang ,在zh-cn 复制想对应的文件包 改下名称就有可以 如:admin_ ...
- array_fill 用给定的值填充数组
转自:http://www.phpstudy.net/php/165.html PHP array_fill 用给定的值填充数组 array_fill (PHP 4 >= 4.2.0, PHP ...
- dijkstra算法求最短路
艾兹格·W·迪科斯彻 (Edsger Wybe Dijkstra,1930年5月11日~2002年8月6日)荷兰人. 计算机科学家,毕业就职于荷兰Leiden大学,早年钻研物理及数学,而后转为计算学. ...
- MySQL创建一个用户,指定一个数据库 授权
Mysql 创建一个用户 hail,密码 hail,指定一个数据库 haildb 给 hail mysql -u root -ppassworduse mysql;insert into user(h ...
- Eclipse构建Maven项目
1. 安装m2eclipse插件 要用Eclipse构建Maven项目,我们需要先安装meeclipse插件 点击eclipse菜单栏Help->Eclipse Marketpl ...