- 浏览: 590573 次
- 性别:
- 来自: 西安
文章分类
- 全部博客 (365)
- Java 基础知识(笔试面试有用) (35)
- SQL 相关 (11)
- Oracle笔试 (1)
- Java 笔试面试 (11)
- LINUX (12)
- ExtJS (21)
- Javascript (17)
- WebGIS (2)
- 软件工程 (3)
- 数据库 (17)
- 项目管理 (63)
- 工作流 (2)
- 计算机网络 (3)
- ZigBee技术及应用 (24)
- 单片机(AVR Studio) (7)
- 项目人力资源管理 (3)
- 项目管理高级知识 (4)
- JAVA技术 (12)
- 项目管理中的概念 (3)
- SQL SERVER (1)
- C++ (1)
- C/C++编程经验 (12)
- C和C++面试笔试题 (12)
- 其他IT技术笔试面试 (6)
- 名企笔试面试集锦 (16)
- 非技术 (10)
- C#相关 (1)
- Matlab相关 (2)
- 计算机专业课相关 (2)
- Web Service (1)
- Excel 使用 (1)
- PhotoShop相关 (4)
- ASP 相关 (2)
- android (1)
- Java WEB 相关 (1)
- web 安全相关 (7)
- 网络安全 (1)
- IBatis (1)
- web 开发技巧 (2)
- css 相关 (1)
- Ruby相关 (2)
- 生活 (3)
- 操作系统安全相关 (6)
- 操作系统相关 (1)
- PHP相关 (3)
- 开发经验 (12)
- Redis (1)
最新评论
阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一
定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。
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()
方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用
中我们应该灵活使用各种方法,以便更好地达到我们的目的。
方法 |
方法说明 |
sleep() |
允许指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间 |
suspend() |
suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。 |
resume() |
对调用过suspend()的线程调用resume(),可使其重新进去可执行状态 |
yield() |
yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间 |
wait() |
wait() 使得线程进入阻塞状态,它有两种形式,一种允许指定以毫秒为单位的一段时间作为参数,另一种没有参数 |
notify() |
有参数的notify()调用当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,没有参数的notify()调用则必须对应的 notify() 被调用。 |
发表评论
-
Java 反射实例
2012-12-21 11:19 1342import java.lang.reflect.Met ... -
java.lang.IndexOutOfBoundsException: replaceAll 转义
2012-12-12 13:10 1183java.lang.IndexOutOfBoundsEx ... -
Java 设计模式
2012-09-25 22:19 3638Java设计模式-图解-附代码 ... -
Java 基础学习
2012-09-25 22:17 915Java语言基础 谈到Java语言基础学习的书籍, ... -
转载的一篇关于如何优化JAVA代码及提高效率的文章
2012-09-23 09:49 2162可供程序利用的资源(内存、CPU时间、网络带宽等)是有限 ... -
面向对象
2012-09-21 21:04 923重写方法规则如下: * 变元 ... -
声明和访问控制
2012-09-19 09:00 1008Java合法标识符规范 (1)标识符必须以字母,货币符 ... -
break continue 用法
2012-09-07 08:48 10671.一般的用法:continue 和break用于跳出循 ... -
用Java实现常用排序算法
2012-09-01 17:02 847package com.zhaopin; publ ... -
JAVA面试宝典-05
2012-08-22 22:25 1122101、java中会存在内存泄 ... -
JAVA面试宝典-04
2012-08-22 22:18 83371、简述synchronized和java. ... -
JAVA面试宝典-03
2012-08-22 22:16 89651、垃圾回收的优点和 ... -
JAVA面试宝典-02
2012-08-22 22:14 92311、HashMap和Hashtable的区别。 HashM ... -
JAVA面试宝典-01
2012-08-22 22:11 8771、String是最基本的数据 ... -
JAVA 3D 开发
2012-04-17 09:36 1512import java.applet.Applet ... -
fatJar 安装与使用
2012-04-06 21:50 2116打包成双击可执行的jar文件。 推荐插件:fat ... -
Java 初始化
2011-10-22 10:54 990Java中方法的局部变量必须要初始化,否则不能使用和操作, ... -
Java 清理
2011-10-22 10:03 897在static方法内部不能调用非静态方法,反过来是可以的。 ... -
Java 构造器
2011-10-22 09:15 750在构造其中可以用this调用一个构造器,但却不能调用两个。 ... -
return break continue
2011-10-21 19:44 1100return :两方面的用途,一方面指定一个方法返回什么值,另 ...
相关推荐
Java线程唤醒与阻塞常用方法共2页.pdf.zip
java 多线程 同步阻塞 唤醒
本文主要向大家分享了Java多线程中的阻塞与唤醒的相关内容,通过这篇文章大家可以大致了解到进入线程阻塞状态和可执行状态的方法,需要的朋友可以了解下。
java 线程状态、线程池 1. java 的线程状态 状态 发生条件 ...通过一个wait方法线程进入一个无线等待状态,需要另一个线程进行唤醒操作 TIME_WAITING(计时等待) 当前进程会在一定时间后从等待
以图表形式详细列出java线程生命周期,创建线程,线程就绪,线程阻塞,线程中断,线程唤醒,线程运行之间的关系
Java中的线程让步会让线程让出优先级,而休眠则会让线程进入阻塞状态等待被唤醒,这里我们对比线程等待的wait()方法,来详解Java中的线程让步yield()与线程休眠sleep()方法
什么时候唤醒,什么时候线程进入阻塞状态。 针对于这个,我的想法是当一个线程读取一段长度的文件之后进入阻塞状态,然后另一个线程继续读取。 如何让线程从文件的指定位置读取。 我问了下度娘,度娘告诉我 file....
LockSupport类提供了park()和unpark()两个方法来实现线程的阻塞和唤醒,下面我们就来详解Java多线程编程中LockSupport类的线程阻塞用法:
什么是线程和进程? **进程与线程的区别? 什么是TreeMap ... Java 中你怎样唤醒一个阻塞的线程? 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。 多线程同步有哪几种方法? 什么是自旋?
③阻塞、唤醒:利用系统提供的线程类模仿进程,直接启动相关的系统调用即可使线程暂停或恢复,从而达到阻塞和唤醒的目的; 针对需求3 :通过编写P、V原语来实现进程的同步; 针对需求4:为进程管理器类编写调度函数...
Java中的阻塞队列原理与使用.mp4 实战:简单实现消息队列.mp4 并发容器ConcurrentHashMap原理与使用.mp4 线程池的原理与使用.mp4 Executor框架详解.mp4 实战:简易web服务器(一).mp4 实战:简易web服务器(二)....
③阻塞、唤醒:利用系统提供的线程类模仿进程,直接启动相关的系统调用即可使线程暂停或恢复,从而达到阻塞和唤醒的目的; 针对需求3 :通过编写P、V原语来实现进程的同步; 针对需求4:为进程管理器类编写调度函数...
Java2023年最新高级面试题及答案,企业真面试题.md 免费下载,不需要积分 ... Java 中你怎样唤醒一个阻塞的线程? 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。 多线程同步有哪几种方法?
什么是线程和进程? **进程与线程的区别? 什么是TreeMap ... Java 中你怎样唤醒一个阻塞的线程? 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。 多线程同步有哪几种方法? 什么是自旋
本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...
使用非阻塞队列的时候有一个很大问题是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,必须额外地实现同步策略以及线程间唤醒策略,这个实现起来非常麻烦。但是有了阻塞队列不一样了,它会
java锁和同步器框架的核心 AQS: AbstractQueuedSynchronizer,就是通过调用 LockSupport .park()和 LockSupport .unpark()实现线程的阻塞和唤醒 的。 LockSupport 很类似于二元信号量(只有1个许可证可供使用),如果...
第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:11:07分钟 | 第51节并发容器ConcurrentHashMap原理与使用00:38:22分钟 | 第52节线程池的原理与使用00:42:49分钟 | 第53节...
第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:11:07分钟 | 第51节并发容器ConcurrentHashMap原理与使用00:38:22分钟 | 第52节线程池的原理与使用00:42:49分钟 | 第53节...