转 Java中wait和sleep方法的区别
1、两者的区别
- 这两个方法来自不同的类分别是Thread和Object
- 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。
- wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
- sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
- sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。
- 注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程
- wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。
waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生illegalMonitorStateException的异常。
补充两个重要的方法:yield()和join()
yield方法
暂停当前正在执行的线程对象。
yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。如果没有的话,那么yield()方法将不会起作用,并且由可执行状态后马上又被执行。
join方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。
说一下为什么使用wait()方法时,一般是需要while循环而不是if?
while(!执行条件) {
wait();
}
.... if(!执行条件) {
wait();
}
....
while会一直执行循环,直到条件满足,执行条件才会继续往下执行。if只会执行一次判断条件,不满足就会等待。这样就会出现问题。
我们知道用notify() 和notifyAll()可以唤醒线程,一般我们常用的是notifyAll(),因为notify(),只会随机唤醒一个睡眠线程,并不一定是我们想要唤醒的线程。如果使用的是notifyAll(),唤醒所有的线程,那你怎么知道他想唤醒的是某个正在等待的wait()线程呢,如果用while()方法,就会再次判断条件是不是成立,满足执行条件了,就会接着执行,而if会直接唤醒wait()方法,继续往下执行,根本不管这个notifyAll()是不是想唤醒的是自己还是别人,可能此时if的条件根本没成立。
举个例子:
while去水果店买苹果,没有了,然后while就和水果店老板说,有水果的时候通知我,我先回去了。if也去水果店买苹果,没有了,然后if就和水果店老板说,有水果的时候通知我,我先回去了。过一段时间,水果店老板发短信告诉while和if,有水果了,while去一看,水果店只是进了香蕉,并不是苹果,所以不是想要的水果,于是回去继续等水果店老板通知,而if根本就不看是不是自己想要的苹果,直接就叫老板送10斤水果过来,这样会导致你得到错误的结果。
参考文献:
Java中wait 和sleep 方法比较
转 Java中wait和sleep方法的区别的更多相关文章
- Java中wait和sleep方法的区别
1.两者的区别 这两个方法来自不同的类分别是Thread和Object 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁). wait ...
- Java中start和run方法的区别
一.问题引入 说到这两个方法就不得不说多线程,说到多线程就不得不提实现多线程的两种方式继承Thread类和实现Runable接口,下面先看这两种方式的区别. 二. Java中实现多线程 ...
- java中构造方法和普通方法的区别
1.普通方法: 定义:简单的说方法就是完成特定功能的代码块. 普通方法定义格式: 修饰符 返回值类型 方法名 (参数类型 参数名1,参数类型 参数名2,.........) { 函数体: re ...
- java 中sendredirect()和forward()方法的区别
一.文章1 HttpServletResponse.sendRedirect与RequestDispatcher.forward方法都可以实现获取相应URL资源. sendRedirect实现请求重 ...
- Java中构造方法跟普通方法的区别?
构造方法与普通方法的调用时机不同. 首先在一个类中可以定义构造方法与普通方法两种类型的方法,但是这两种方法在调用时有明显的区别. 1.构造方法是在实例化新对象(new)的时候只调用一次 2.普通方法是 ...
- java中getAttribute与getParameter方法的区别
知识点1:getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为object对象类型 例: r ...
- Java中==号与equals()方法的区别
String str1 = new String("abc"); String str2 = new String("abc"); System.out.pri ...
- Java 中 interrupted 和 isInterrupted 方法的区别?
interrupt interrupt 方法用于中断线程.调用该方法的线程的状态为将被置为"中断"状态. 注意:线程中断仅仅是置线程的中断状态位,不会停止线程.需要用户自己去监 视 ...
- 面试常见问题:java中wait()和sleep()方法的区别
wait()和sleep()方法都是用来控制多线程的有力工具,那么它们之间有什么巨大的区别呢? 1.wait()方法是属于Object类的,而sleep()方法是属于Thread类的. 2.最重要的一 ...
随机推荐
- 高清摄像头MIPI接口与ARM连接【转】
本文转载自:http://www.cnblogs.com/whw19818/p/5811299.html MIPI摄像头常见于手机.平板中,支持500万像素以上高清分辨率.它的全称为“Mobile I ...
- 虚拟主机支持apk
扩展名中填写.apk MIME类型中填写apk的MIME类型 application/vnd.android.package-archive
- Flask中的路由配置
在Flask中也同样有django中的路由配置只不过没有djngo那么严格主要的参数有一下六个记住常用的就可以了 1.endpoint 反向生成url地址标志,默认视图函数名 2.methods ...
- 豆瓣镜像安装python库
- 测开之路九十五:css进阶之光标和溢出内容处理
光标样式:cursor 准备文字 css 溢出内容处理:overflow,默认溢出部分是显示 先把内容放到盒子里面 正常显示 不显示溢出内容 显示为滚动条 自动处理 css /* 光标样式 */p{ ...
- 查询SQL Server数据库所有表字段备注
SELECT 表名 = case when a.colorder=1 then d.name else '' end, 表说明 = case when a.colorder=1 then isnull ...
- 怎么用 pytorch 查看 GPU 信息
如果你用的 Keras 或者 TensorFlow, 请移步 怎么查看keras 或者 tensorflow 正在使用的GPU In [1]: import torch In [2]: torch.c ...
- 链表两数相加(add two numbers)
问题 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它 ...
- HTTP response status
The status code is a 3-digit number: 1xx (Informational): Request received, server is continuing the ...
- OuterXml和InnerXml(2)
官方例子:https://msdn.microsoft.com/en-us/library/system.xml.xmlnode.outerxml.aspx using System; using S ...