论wait跟notify的正确使用方法-简单锁的实现

论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;
		
	}

}