Silentdoer

导航

java sleep和wait方法的区别,可重入锁的概念

1.sleep是Thread里的静态方法,表示将当前线程睡眠一段时间的意思,它不会释放在此线程此时synchronized(lock)的lock对象的锁;

2.wait方法是任意对象都有的方法,任意对象都能被synchronized,当对对象obj.wait()时,如果当前线程已经通过synchronized(obj)对obj进行了加锁,则obj.wait()会造成当前线程对obj的锁释放,

从而其他线程此时如果在等待synchronized(obj)的锁会立刻获得锁;【注意,这个不适用ReentrantLock对象,比如lock.lock()在非创建lock对象的线程,然后lock.wait()是会报错的】

而obj.wait()后会处于条件等待状态,此时需要通过obj.notify()来通知解除这样的状态;

注意obj.wait()可以被多个线程执行,如果要同时唤醒这几个线程,可以用obj.notifyAll(),否则obj.notify()是随机唤醒一个的(具体是什么顺序不同实现不一样,但是官方没有保证一定是先wait的先被notify唤醒);

注意,lock.lock()和synchronized(lock)不是一个概念;

 

现在不建议用obj.wait(),而是用java8里的Condition,通过Lock来创建;(condition.await()时也是会释放对应的lock锁;condition.signal()就类似obj.notify(),必须在临界区里执行signal()方法)

 

注意lock的condition进行await时是让出锁(但是线程本身其实还是有锁相关的信息的),和释放锁不是完全相等(即不能完全等价unlock),因为await导致其他地方也能获得lock,而其他地方对condition进行signal通知后;

使得await的地方继续执行,最终执行unlock,如果await是等价于unlock,则二次unlock是会抛异常的(没有二次lock()的前提下),而这里没有,说明await只是让出锁(或说允许另一个线程也能获得lock),但不是释放锁;

 

3.可重入锁有ReentrantLock和synchronized的两种

且可重入锁是指针对一个线程可以lock()多次,但也必须unlock多次才能解锁(而且必须在lock的线程里unlock否则抛异常);

如果是不可重入锁的话,则同一个线程a,第一次lock1.lock();得到了锁,然后在该线程释放lock1锁之前又进行了lock1.lock()就会造成等待从而产生死锁。

posted on 2023-11-12 17:27  Silentdoer  阅读(29)  评论(0编辑  收藏  举报