不可重入鎖、可重入鎖的實現以及測試
阿新 • • 發佈:2019-01-27
可重入鎖定義:執行緒去請求自己擁有的鎖可請求到
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()...
部落格沒教材系統,多看書比較靠譜,書上可能程式碼少了些