wait方法和sleep方法的区别
一.概念、原理、区别
共同点: 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
不同点: Thread.sleep(long)可以不在synchronized的块下调用,而且使用Thread.sleep()不会丢失当前线程对任何对象的同步锁(monitor);
object.wait(long)必须在synchronized的块下来使用,调用了之后失去对object的monitor, 这样做的好处是它不影响其它的线程对object进行操作。
举个java.util.Timer的例子来说明。
private void mainLoop() {
while (true) {
....
synchronized(queue) {
.....
if (!taskFired) // Task hasn't yet fired; wait
queue.wait(executionTime - currentTime);
}
}
在这里为什么要使用queue.wait(),而不是Thread.sleep(), 是因为暂时放弃queue的对象锁,可以让允许其它的线程执行一些同步操作。如:
private void sched(TimerTask task, long time, long period) {
synchronized(queue) {
...
queue.add(task);
}
}
但是正如上篇文章讲到的,使用queue.wait(long)的前提条件是sched()动作执行的时间很短,否则如果很长,那么queue.wait()不能够按时醒来。
二. Thread的Interrupt方法与Sleep,Wait
前面讲了wait/notify机制,Thread还有一个sleep()静态方法,它也能使线程暂停一段时间。sleep与wait的不同点是:sleep并不释放锁,并且sleep的暂停和wait暂停是不一样的。obj.wait会使线程进入obj对象的等待集合中并等待唤醒。
但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。
三.转载CSDN上关于Sleep,Wait的一段代码,并分析理解下
下面是我原来在CSDN论坛上看到的一个贴子,涉及到同步,wait(),notify()等概念的理解,我试着根据原来的一些回复和Think in Java上的相关概念将wait()和notify()这两个方法剖析了一下,欢迎指教.
问题如下:
分析这段程序,并解释一下,着重讲讲synchronized、wait(),notify 谢谢!
class ThreadA
{
public static void main(String[] args)
{
ThreadB b=new ThreadB();
b.start();
System.out.println("b is start....");
synchronized(b)//括号里的b是什么意思,起什么作用?
{
try
{
System.out.println("Waiting for b to complete...");
b.wait();//这一句是什么意思,究竟让谁wait?
System.out.println("Completed.Now back to main thread");
}catch (InterruptedException e){}
}
System.out.println("Total is :"+b.total);
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("ThreadB is running..");
for (int i=0;i<100;i++ )
{
total +=i;
System.out.println("total is "+total);
}
notify();
}
}
}
要分析这个程序,首先要理解notify()和wait(),为什么在前几天纪录线程的时候没有纪录这两个方法呢,因为这两个方法本来就不属于Thread类,而是属于最底层的object基础类的,也就是说不光是Thread,每个对象都有notify和wait的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了.
再往下看之前呢,首先最好复习一下Think in Java的14.3.1中第3部分内容:等待和通知,也就是wait()和notify了.
按照Think in Java中的解释:"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."
我们来解释一下这句话.
"wait()允许我们将线程置入“睡眠”状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的.那和sleep,suspend有什么区别呢?
区别在于"(wait)同时又“积极”地等待条件发生改变",这一点很关键,sleep和suspend无法做到.因为我们有时候需要通过同步(synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁,其它要使用该对象锁的线程都只能排队等着,等到同步方法或者同步块里的程序全部运行完才有机会.在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放.
而wait却可以,它可以让同步方法或者同步块暂时放弃对象锁,而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用,这意味着可在执行wait()期间调用线程对象中的其他同步方法!在其它情况下(sleep啊,suspend啊),这是不可能的.
但是注意我前面说的,只是暂时放弃对象锁,暂时给其它线程使用,我wait所在的线程还是要把这个对象锁收回来的呀.wait什么?就是wait别人用完了还给我啊!
好,那怎么把对象锁收回来呢?
第一种方法,限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明我只借出去1秒中,一秒钟之后,我自动收回.
第二种方法,让借出去的人通知我,他用完了,要还给我了.这时,我马上就收回来.哎,假如我设了1小时之后收回,别人只用了半小时就完了,那怎么办呢?靠!当然用完了就收回了,还管我设的是多长时间啊.
那么别人怎么通知我呢?相信大家都可以想到了,notify(),这就是最后一句话"而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒"的意思了.
因此,我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否准备进行涉及线程的处理。而且实际上,我们也只能在同步方法或者同步块里面调用wait()和notify().
这个时候我们来解释上面的程序,简直是易如反掌了.
synchronized(b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()通知wait的线程,锁已经用完,待notify()所在的同步块运行完之后,wait所在的线程就可以继续执行.
wait方法和sleep方法的区别的更多相关文章
- ThinkPHP的D方法和M方法的区别
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- M方法和D方法的区别
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别 关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来 ...
- Exception 的 toString() 方法和 getMessage() 方法的区别
Exception 的 toString() 方法和 getMessage() 方法的区别: 在开发的过程中打印错误日志时尽量使用e.toString() 方法, 因为当错误为空指针时 e.getMe ...
- ExtJS中listener方法和handler方法的区别
listener方法和handler方法的区别在文档中的说明的太玄乎了,看不懂 listeners监听能够对一个click Event事件添加任意多个的事件响应处理函数 而handler处理只能够通过 ...
- MongoDB save()方法和insert()方法的区别
MongoDB save()方法和insert()方法的区别 首先看官方文档怎么说的 Updates an existing document or inserts a new document, d ...
- 问题:ExecuteNonQuery 与 ExecuteScalar 结果: ExecuteNonQuery方法和ExecuteScalar方法的区别
ExecuteNonQuery方法和ExecuteScalar方法的区别 ----ExecuteNonQuery():执行命令对象的SQL语句,返回一个int类型变量,如果SQL语句是对数据库的记录进 ...
- 2016/05/23 thinkphp M方法和D方法的区别
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- GET方法和POST方法的区别,Get方法到底可传递的字符串的最大长度是多少?
GET方法和POST方法的区别,Get方法到底可传递的字符串的最大长度是多少?曾经人介绍,如果使用GET方式传输参数,URL的最大长度是256个字节,对此深信不疑. 但是最近看到一些超长的url,能够 ...
- sleep()方法和wait()方法的区别? sleep()方法和yield()方法的区别?
sleep()方法和wait()方法的区别? sleep方法是Thread的静态方法,wait方法是Object类的普通方法 sleep方法不释放同步锁,wait方法释放同步锁(执行notify方法唤 ...
随机推荐
- OS X(EI Capitan)常用快捷键整理
刚上班就配了台RMBP,虽然触摸板确实好用,但是对鼠标的支持太差导致无法使用鼠标,而某些功能用触摸板还是不很方便 于是使用快捷键就势在必行了,参考了苹果官方文档和一些其他资料,整理出常用快捷键清单 准 ...
- 《构建之法》第8、9、10章 读书笔记和Sprint总结
第八章:需求分析 这章主要解析了需求的多面方面,不同的项目需要不同的手段,真正的需求稍纵即逝,需要靠火眼金睛和敏捷的身手来发现并抓住它们.另外,很多时候用户并不知道自己确切的需求,或者不愿意表达完整的 ...
- SVN 忽略文件但不删除文件
SVN忽略一些不必要的文件但不删除 如果svn仓库中有一些不希望被别人提交的文件 该如何忽略掉对这个文件的更改但又不删除这个文件呢? 在找了一堆解决方案后得出了如下结论 去除要被忽略文件的版本控制 基 ...
- DataTable 获取列名 DataTable批量更新至数据库
好久没写东西了,这几个月也没下功夫钻研技术,愧疚啊.说下最近刚学会的DataTable 的用法吧,新手适合看下. 1 DataTable 获取列名 在处理数据的时候大家都会用到模型,从datatabl ...
- 多余的Using Namespaces或引用会影响程序的执行效率么?
在.NET程序编写中,需要using相应命名空间或添加相应的References,可有时候没有使用到的命名空间也被添加到了Using Namespaces中,那么,这样会影响程序的执行效率么? 通过示 ...
- AC自动机---Searching the String
ZOJ 3228 题目网址:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16401 Description Little ...
- js 自带的 sort() 方法
1. 方法概述 Array的sort()方法默认把所有元素先转换为String再根据Unicode排序, sort()会改变原数组,并返回改变(排序)后的数组 . 2. 例子 2.1 如果没有提供自定 ...
- react与redux学习资料的整理
**重点内容**React学习 1.新手入门可以访问react的官方网站,如果英语不是特别好的同学可以访问中文版的,具体链接http://reactjs.cn/react/index.html 首页有 ...
- 自定义View_1_关于View,ViewGroup的测量和绘制流程
自定义View(1) ------ 关于View,ViewGroup的测量和绘制流程 在Android当中,自定义控件属于比较高级的知识体系,今天我们就一起研究研究关于自定义View的那点事,看看它到 ...
- Android5.0新特性——兼容性(support)
兼容性 虽然Material Design新增了许多新特性,但是并不是所有新内容对对下保持了兼容. 使用v7包 v7 support libraries r21 及更高版本包含了以下Material ...