1. 程式人生 > 實用技巧 >Java 鎖的簡單理解

Java 鎖的簡單理解

可重入鎖 與 不可重入鎖

原理就是當前執行緒訪問的資源的時候,可以用獲取執行緒名判斷是否是同一個執行緒,如果是的話就可以訪問其他資源,同時計數器加一。不是的話wait等待。

當退出時,計數器減一。如果計數器為零,代表執行完成,使用notify喚醒即可。

也可以使用JDK已經封裝好的類ReentrantLock

可重入鎖程式碼

package mobai.others;
/**
 * 模擬可重入鎖 鎖可以延續使用 + 計數器
 * @author MAIBENBEN
 *
 */
public class LockTest03 {
	ReLock lock = new ReLock();
	public void a() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		doSomething();
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}
	//可重入
	public void doSomething() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		System.out.println("-*-*-*-*-*-");	
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}

	public static void main(String[] args) {
		LockTest03 test = new LockTest03();
		try {
			test.a();
			Thread.sleep(1000);
			System.out.println(test.lock.getHoldCount());
		} catch (InterruptedException e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
		}
	}
}
//可重入鎖
class ReLock{
	//是否使用
	private boolean isLock = false;
	Thread lockedBy = null;//儲存執行緒
	private int holdCount = 0;
	public int getHoldCount() {
		return holdCount;
	}
	public void setHoldCount(int holdCount) {
		this.holdCount = holdCount;
	}
	//使用鎖
	public synchronized void lock() throws InterruptedException {
		Thread t = Thread.currentThread();
		while(isLock&&lockedBy!=t) {
			wait();
		}
		isLock = true;
		lockedBy = t;
		holdCount++;
	}
	//釋放鎖
	public synchronized void unlock(){
		if(Thread.currentThread()==lockedBy) {
			holdCount--;
		}
		if(holdCount==0) {
			isLock = false;
			notify();
			lockedBy = null;
		}
	}
}