Java线程唤醒与阻塞
阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一
定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。
转载于:http://blog.csdn.net/small____fish/article/details/7726468
1. sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间
内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。
典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后
重新测试,直到条件满足为止。
2. suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会
自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和
resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个
线程产生了结果后,调用 resume() 使其恢复。
3. yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于
可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足
够的时间从而转到另一个线程。
4. wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式
,一种允许指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或
者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。
初看起来它们与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区
别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则
相反。
上述的核心区别导致了一系列的细节上的区别。
首先,前面叙述的所有方法都隶属于 Thread 类,但是这一对却直接隶属于 Object 类,也就是说,
所有对象都拥有这一对方法。初看起来这十分不可思议,但是实际上却是很自然的,因为这一对方法阻塞
时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象
上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随
机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
其次,前面叙述的所有方法都可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块
中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的
道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调
用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若
不满足这一条件,则程序虽然仍能编译,但在运行时会出现 IllegalMonitorStateException 异常。
wait() 和 notify() 方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和
操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作
系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则相当于 block 和wakeup 原语
(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间
通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。
关于 wait() 和 notify() 方法最后再说明两点:
第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随
机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问
题。
第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用
notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有
获得锁的那一个线程才能进入可执行状态。
谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait()
方法的调用都可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,我们在编程中必须小
心地避免死锁。
以上我们对 Java 中实现线程阻塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify()
方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用
中我们应该灵活使用各种方法,以便更好地达到我们的目的。
总结:
wait和notify、notifyall方法属于Object类,它们涉及到锁的释放问题,所以和synchronized关键字一起使用。
suspend() 和 resume() 方法配套使用。
Java线程唤醒与阻塞的更多相关文章
- 简单测试Java线程安全中阻塞同步与非阻塞同步性能
摘抄自周志明老师的<深入理解Java虚拟机:JVM高级特性与最佳实践>13.2.2 线程安全的实现方法 1.名词解释 同步是指锁哥线程并发访问共享数据时,保证共享数据同一时刻只被一个线程访 ...
- Java线程--BlockingQueue使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871704.html Java线程--BlockingQueue使用 阻塞队列就是内容满了之 ...
- 多线程之Java线程阻塞与唤醒
线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题.如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节.在Java ...
- java - 线程等待与唤醒
Java多线程系列--“基础篇”05之 线程等待与唤醒 概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. w ...
- 面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
摘要: 原创出处 https://studyidea.cn 「公众号:程序通事 」欢迎关注和转载,保留摘要,谢谢! 使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而 ...
- 一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 21.对线程安全的理解 22.Thread和Runnable的区别 23.说说你对守护线程的理解 24.ThreadLoc ...
- java线程自带队列的使用以及线程阻塞
java线程,设置队列的大小实现队列阻塞 public class QueueThreads { private static int nThreads = 4;//Runtime.getRuntim ...
- 转:JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue
从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构 ...
- java线程(7)——阻塞队列BlockingQueue
回顾: 阻塞队列,英文名叫BlockingQueue.首先他是一种队列,联系之前Java基础--集合中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了.来看一下他们的接口 ...
随机推荐
- Git、Github、码云 笔记汇总
从本地恢复码云的项目 把本地项目同步到码云 CBoard 基于0.4.1的旧版本的分支修改合并到0.4.2新版本里面 通过git命令行把一个分支的其中一个commit(提交)合并到另外一个分支里面去
- 【性能测试】:关于loadrunner11录制Chrome浏览器脚本的方法
有些web端的程序只能通过chrome访问,如果用lr11录制的话,会抓不到包, 现在教一种方法,可以抓到包的,主体思路就是设置代理,让报文流量绕道走一下 一,在LR中的设置: 从菜单Tools-Re ...
- python GIL(Global Interpreter Lock)
一 介绍 ''' 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple nati ...
- CentOS和Ubuntu系统下安装 HttpFS (助推Hue部署搭建)
不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...
- casperjs问题收集
1 无妨访问某些页面可能是ssl选项没有使用 casperjs --ignore-ssl-errors=true --ssl-protocol=any 你的测试文件
- Wireshark命令行工具tshark详解(含例子)-01
Wireshark命令行工具tshark使用小记 1.目的 写这篇博客的目的主要是为了方便查阅,使用wireshark可以分析数据包,可以通过编辑过滤表达式来达到对数据的分析:但我的需求是,怎么样把D ...
- [PY3]——函数——生成器(yield关键字)
函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...
- [shell进阶]——shell多线程
关于shell的多线程 1. 多线程并发执行任务,而不用一台台的串行执行,能更快更高效 2. Shell并没有多线程的概念,所以: * 一般使用wait.read等命令技巧性地模拟多线程实 * 使用命 ...
- C#实现文件下载的几种方式
上篇博客也说了下C#中通过XML导出Excel,这些文件操作都挺有用的,下面是文件的下载,之前做项目都是把它写的空间日志中,以后有时间了把它们都弄出来 先把有问题的代码贴出来吧 using Syste ...
- 选择适用才最好 盘点MySQL备份方式
我们要备份什么? 一般情况下, 我们需要备份的数据分为以下几种 数据 二进制日志, InnoDB事务日志 代码(存储过程.存储函数.触发器.事件调度器) 服务器配置文件 备份工具 这里我们列举出常用的 ...