Art of Multiprocessor Programming 答案 ch8
2014-04-15 20:15
387 查看
93.
94.
会有 readlock.lock() --> readwait > readrelease --> writelock.lock() --> write = true --> waiting for readwait == readrelease ==> deadlock
其他的线程会有 write == true ==> block
95. 不一定全部会返回,因为可能在别人的cond上死锁,boss notify自己的锁线程感应不到。比如下面的case:
96.
97.
98.
package p93; import java.util.concurrent.locks.Lock; public class SimpleRWLock { private class ReadLock implements Lock { public void lock() { try { synchronized(lockObj) { while(writer) { lockObj.wait(); } readers ++; } }catch(Exception e) { e.printStackTrace(); } } public void unlock() { synchronized(lockObj) { if(readers <= 0) { lockObj.notifyAll(); } } } public void lockInterruptibly() throws java.lang.InterruptedException { throw new InterruptedException(); } public boolean tryLock() { return false; } public boolean tryLock(long arg0, java.util.concurrent.TimeUnit arg1) throws java.lang.InterruptedException { throw new InterruptedException(); } public java.util.concurrent.locks.Condition newCondition() { return null; } } private class WriteLock implements Lock { public void lock() { try { synchronized(lockObj) { while(readers > 0 || writer) { lockObj.wait(); } writer = true; } }catch(Exception e) { e.printStackTrace(); } } public void unlock() { synchronized(lockObj) { writer = false; lockObj.notifyAll(); } } public void lockInterruptibly() throws java.lang.InterruptedException { throw new InterruptedException(); } public boolean tryLock() { return false; } public boolean tryLock(long arg0, java.util.concurrent.TimeUnit arg1) throws java.lang.InterruptedException { throw new InterruptedException(); } public java.util.concurrent.locks.Condition newCondition() { return null; } } private int readers; private boolean writer; private Object lockObj; private ReadLock readLock; private WriteLock writeLock; public SimpleRWLock() { lockObj = new Object(); readLock = new ReadLock(); writeLock = new WriteLock(); } public Lock readLock() { return readLock; } public Lock writeLock() { return writeLock; } public static void main(String[] args) { SimpleRWLock lock = new SimpleRWLock(); lock.readLock().lock(); lock.readLock().unlock(); lock.writeLock().lock(); lock.writeLock().unlock(); } }
94.
会有 readlock.lock() --> readwait > readrelease --> writelock.lock() --> write = true --> waiting for readwait == readrelease ==> deadlock
其他的线程会有 write == true ==> block
95. 不一定全部会返回,因为可能在别人的cond上死锁,boss notify自己的锁线程感应不到。比如下面的case:
package p95; public class Prefer { private int balance; private int preferRequests; public static final int PREFER = 1; public static final int NORMAL = 2; public Prefer() { balance = 0; preferRequests = 0; } public Prefer(int initial) { this(); balance = initial; } private void deposit_nolock(int k) { balance += k; } public synchronized void deposit(int k) { deposit_nolock(k); this.notifyAll(); } public synchronized void withdraw(int k, int style) { try { switch(style) { case NORMAL: while(preferRequests > 0 || balance < k) { this.wait(); } balance -= k; break; case PREFER: preferRequests ++; while(balance < k) { this.wait(); } balance -= k; preferRequests --; this.notifyAll(); break; default: throw new InterruptedException(); } }catch(InterruptedException e) { this.notifyAll(); } } public synchronized void transfer(Prefer other, int k) { other.withdraw(k, NORMAL); deposit_nolock(k); } }
package p95; public class TestThread extends Thread { private Prefer myAccount; private Prefer otherAccount; public final int WITHDRAW = 200; public final int BOSS = 1000; public TestThread(Prefer me, Prefer other) { this.myAccount = me; this.otherAccount = other; } public void run() { System.out.println("To transfer "); myAccount.transfer(otherAccount, WITHDRAW); System.out.println("End of transfer "); } public void boss() { myAccount.deposit(BOSS); } public static void main(String[] args) { Prefer[] accounts = new Prefer[2]; for(int i = 0; i < accounts.length; i ++) { accounts[i] = new Prefer(0); } TestThread tester1 = new TestThread(accounts[0], accounts[1]); TestThread tester2 = new TestThread(accounts[1], accounts[0]); tester1.start(); tester2.start(); try { Thread.sleep(1000); }catch(Exception e) { e.printStackTrace(); } System.out.println("After sleep "); tester1.boss(); tester2.boss(); } }
96.
package p96; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Bathroom_1 { private Lock lock; private Condition maleCond; private Condition femaleCond; private int maleAcq; private int maleRel; private int femaleAcq; private int femaleRel; private int maleWait; private int femaleWait; public static final int MALE = 1; public static final int FEMALE = 2; public Bathroom_1() { lock = new ReentrantLock(); maleCond = lock.newCondition(); femaleCond = lock.newCondition(); } public void maleEnter() { lock.lock(); try { maleWait ++; while((femaleWait != femaleAcq && maleAcq != maleRel) || (femaleAcq != femaleRel)) { maleCond.await(); } maleAcq ++; }catch(Exception e) { e.printStackTrace(); maleWait --; maleCond.signalAll(); femaleCond.signalAll(); }finally { lock.unlock(); } } public void maleExit() { lock.lock(); maleRel ++; if(maleRel == maleAcq) { femaleCond.signalAll(); } lock.unlock(); } public void femaleEnter() { lock.lock(); try { femaleWait ++; while((maleWait != maleAcq && femaleAcq != femaleRel) || (maleAcq != maleRel)) { femaleCond.await(); } femaleAcq ++; }catch(Exception e) { e.printStackTrace(); femaleWait --; maleCond.signalAll(); femaleCond.signalAll(); }finally { lock.unlock(); } } public void femaleExit() { lock.lock(); femaleRel ++; if(femaleRel == femaleAcq) { maleCond.signalAll(); } lock.unlock(); } }
97.
package p97; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Rooms { public interface Handler { void onEmpty(); } private Lock lock; private Condition[] conds; private int waiting[]; private int acquire[]; private int release[]; private Handler[] handlers; private final int m; private int currRoom; public Rooms(int m) { this.m = m; lock = new ReentrantLock(); conds = new Condition[m + 1]; for(int i = 0; i < conds.length; i ++) { conds[i] = lock.newCondition(); } waiting = new int[m + 1]; acquire = new int[m + 1]; release = new int[m + 1]; handlers = new Handler[m + 1]; currRoom = -1; } private boolean toWait(int index) { if(currRoom == -1) { return false; } if(currRoom != index) { return true; } for(int i = 1; i <= m; i ++) { int other = (i + index) % (m + 1); if(waiting[other] != acquire[other]) { return true; } } return false; } public void enter(int i) { if(i < 0 || i > m) { return; } lock.lock(); try { waiting[i] ++; while(toWait(i)) { conds[i].await(); } acquire[i] ++; currRoom = i; }catch(Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } private int notifyWho() { for(int i = 1; i <= m; i ++) { int other = (i + currRoom) % (m + 1); if(waiting[other] != acquire[other]) { return other; } } return -1; } public boolean exit() { lock.lock(); release[currRoom] ++; if(release[currRoom] == acquire[currRoom]) { if(handlers[currRoom] != null) { handlers[currRoom].onEmpty(); } int other = notifyWho(); if(other >= 0) { conds[other].signalAll(); } currRoom = -1; } lock.unlock(); return true; } public void setExitHandler(int i, Rooms.Handler handler) { if(i < 0 || i > m) { return; } lock.lock(); handlers[i] = handler; lock.unlock(); } }
98.
package p98; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class CountDownLatch { private Lock lock; private Condition cond; private int m; public CountDownLatch(int m) { this.m = m; lock = new ReentrantLock(); cond = lock.newCondition(); } public void countDown() { lock.lock(); m --; if(m <= 0) { cond.signalAll(); } lock.unlock(); } public void await() { lock.lock(); try { while(m > 0) { cond.await(); } }catch(Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } /* * Lock is not necessary as: * 1. set m at anytime can get matching history * 2. User should take care of reset since I don't want to block reset() method */ public void reset(int m) { lock.lock(); this.m = m; lock.unlock(); } }
相关文章推荐
- Job类
- MINI2440Linux驱动01-mini2440_adc
- 搞ACM的你伤不起(转载,不过这个神作实在是太经典了)
- VMware vSAN虚拟化存储初探
- 新手开车13招技巧
- codeforces Round #241(div2) A解题报告
- ubuntu11.04更新源
- poj3660
- c++的 gettimer() 在哪里? 如何用他计算方法运行时间?
- 随机函数(3)
- week 8
- 新手必看一位老司机的十年开车经验
- 可变参数函数
- Velocity布局祥解
- [USACO]A GAME (博弈+dp)
- python操作Excel读写--使用xlrd
- gopm 下载 网络连接出错
- APNS IOS PHP 苹果推送
- 学开车不能急于求成,心急上路
- DAT (Double Array Trie) 多模式匹配算法