论wait和notify的正确使用方法-简单锁的实现
? ? ? ? ? ?在java中实现某段代码在多个线程中互斥地执行,我们常常用到synchronized同步方法块,那么有什么东西可以代替它呢,就是j.u.c包中的Lock相关的类,该篇讲的是Lock的简单实现。
? ? ? ? ? ?首先明确Lock的使用方法
Lock lock = new Lock();try{ lock.lock(); /********需要互斥的代码**********/}finally{ lock.unlock();}
?
?需要注意的是多个线程中的lock对象必须是同一个,要不然起不到互斥的作用。
?
lock()和unLock()必须成对出现,且unLock()需要放在finally中,避免出现异常造成的死锁
?
如果在其他线程unLock(),就应该抛出IllegalMonitorStateException.
?
实现思路如下:
?
1.为了保证lock和unLock的成双成对,我们需要记录lock的线程,然后和执行unLock的线程进行比较,如果是”李鬼“,就抛出异常。lock和unLock我们已经用synchronized保证是”原子操作“了
public class Lock {private Thread lockedTh = null;public synchronized void lock(){lockedTh =Thread.currentThread();}public synchronized void unLock(){if(lockedTh!=Thread.currentThread()){throw new IllegalMonitorStateException();}lockedTh = null;}}
2.执行Lock之后,其他线程就必须等着,执行unLock之后,就该喊一个线程起来,于是
public class Lock {private Thread lockedTh = null;public synchronized void lock() throws InterruptedException{wait();lockedTh =Thread.currentThread();}public synchronized void unLock(){if(lockedTh!=Thread.currentThread()){throw new IllegalMonitorStateException();}notify();lockedTh = null;}}
?3.上面的版本第一个执行lock的线程也会堵着,所以我们设置一个标志符,如果现在没有锁住,就可以进来,同时改变标志。反之就等着,直到可以进来,所以最终版本是
package com.cici.lock;/** * @author 尹定宇 * @Email 768166775@qq.com * @version 2013-7-14 下午6:48:18 * @info */public class Lock {private boolean isLocked = false;private Thread lockedTh = null;public synchronized void lock() throws InterruptedException{while(isLocked){wait();}lockedTh =Thread.currentThread();isLocked = true;}public synchronized void unLock(){if(lockedTh!=Thread.currentThread()){throw new IllegalMonitorStateException();}notify();isLocked = false;lockedTh = null;}}
?