1. 程式人生 > >不可重入鎖、可重入鎖的實現以及測試

不可重入鎖、可重入鎖的實現以及測試

可重入鎖定義:執行緒去請求自己擁有的鎖可請求到

interface SelfDefineLock{
	void lock();
	void unlock();
}

class Father{
	SelfDefineLock lock;
	Father(SelfDefineLock lock){
		this.lock = lock;
	}
	void do_(){
		lock.lock();
		System.out.println("Father Class " + "Thread " + Thread.currentThread().getName());
		lock.unlock();
	}
}

class Child extends Father{
	Child(SelfDefineLock lock) {
		super(lock);
		// TODO Auto-generated constructor stub
	}
	void do_(){
		lock.lock();
		System.out.println("Child Class " + "Thread " + Thread.currentThread().getName());
		super.do_();
		lock.unlock();
	}
}

class NoRtLock implements SelfDefineLock{
//	private volatile boolean locked = false;
	private boolean locked = false;
	public synchronized void lock(){
		while(locked){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		locked = true;
	}
	public synchronized void unlock(){
		locked = false;
		notify();
	}
}

class RtLock implements SelfDefineLock{
	private volatile boolean locked = false;
	Thread locked_by = null;
	int locked_cnt = 0;
	
	public synchronized void lock(){
		Thread current_thread = Thread.currentThread();
		while(locked && current_thread != locked_by){
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		locked = true;
		locked_by = current_thread;
		++locked_cnt;
	}
	
	public synchronized void unlock(){
		--locked_cnt;
		if(locked_cnt == 0){
			locked = false;
			notify();
		}
	}
}

public class Test {
	static void test_nortlock(){
		SelfDefineLock lock = new NoRtLock(); 
		final Father instance = new Child(lock);
		new Thread(){
			public void run(){
				instance.do_();
			}
		}.start();
	}
	static void test_rtlock(){
		SelfDefineLock lock = new RtLock(); 
		final Father instance = new Child(lock);
		new Thread(){
			public void run(){
				instance.do_();
			}
		}.start();
	}
	public static void main(String[] args){
		test_nortlock();
		test_rtlock();
	}
}

上面RtLock是可重入鎖,NoRtLock是不可重入鎖,執行結果如下:

Child Class Thread Thread-0
Child Class Thread Thread-1

Father Class Thread Thread-1

不可重入鎖發生了死鎖,呼叫

super.do_();

執行到父類函式

void do_(){
		lock.lock();
		System.out.println("Father Class " + "Thread " + Thread.currentThread().getName());
		lock.unlock();
	}
時無法獲取鎖,阻塞在
lock.lock();

上面程式碼需要注意的地方:wait() notify() notifyAll()方法需要由同步監視器呼叫,兩個Lock程式碼中都加入了synchronized程式碼塊,因此內部能夠使用wait()。原本是打算不用synchronized的,而使用volatile修飾locked變數保證現場安全,但是那樣就不用使用wait()等了。另一種辦法使用wait()的辦法是用Condition類來幫忙,新增隱式同步監視器。<<Java瘋狂講義>>中有。Condition cond = Lock.newCondition()...

部落格沒教材系統,多看書比較靠譜,書上可能程式碼少了些