Java多线程-wait、notify、notifyAll和sleep的区别和联系

一、wait()、notify()、notifyAll()作用

首先wait()、notify()、notifyAll()都是Object类的方法,也就是说每个对像都有wait(),notify(),notifyAll()的功能。但是必须保证调用代码对该Object是同步的,也就是说必须在作用于synchronized(obj){......}(或者synchronized修饰的函数)的内部才能够去调用obj的wait与notify/notifyAll三个方法,否则就会报错: java.lang.IllegalMonitorStateException:current thread not owner。

1. wait():等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则虽然编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。

2. notify():唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,notify是一个有序的出队列的过程(wait后的线程会进入一个FIFO的队列中,notify会按wai进入的先后顺序就行唤醒)。而短时间内多个线程竞争获得锁的顺序则是不确定的,这要靠cpu调度决定,只有在获得锁后才会接着之前wait的位置开始执行。

3. notifyAll():唤醒所有等待的线程,注意唤醒的是同一个锁对象notify之前wait的线程,对于notify之后的wait线程是没有效果的。

二、sleep的作用

sleep()方法是在线程类(Thread)中实现的,其调用者是线程对象。sleep()的作用是将当前线程暂停一定的时间,但在这期间并不释放锁。如:Thread.sleep(5000);// 睡眠5秒

三、wait()和sleep的区别

1. 两个方法来自不同的类分别是Object和Thread;
2. 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步代码块或者同步方法,即可以进入锁内部的机会;
3. wait,notify和notifyAll只能同步代码块或同步方法里面使用,而sleep可以在何地方使用;
4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。

四、需要注意的是:

1. 有synchronized的地方不一定有wait,notify

2. 有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。

另外,注意一点:如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是currentthread了。

3. 如果用了显式锁 Lock(java.util.concurrent.locks.ReentrantLock)就不要用 wait() 和 notify() 了,它们是两套加锁机制,不能混着用的,关于ReentrantLock的使用可见ReentrantLock使用详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值