Art of Multiprocessor Programming 答案 ch8 p95

来源:互联网 发布:阿里云系统刷安卓系统 编辑:程序博客网 时间:2024/04/27 23:08



public class Account {    /**优先存款方式*/    public static final int PREFER = 1;    /**普通存款方式*/    public static final int NORMAL = 2;    private int surplus;//结余    private int preferRequests;    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    public Account() {        surplus = 0;        preferRequests = 0;    }    /**     * 结余 += k     *     * @param k     */    public void deposit(int k) {        lock.lock();        try {            surplus += k;            System.out.println("Thread " + Thread.currentThread().getName() + " deposit "+ k);            condition.signalAll();        } finally {            lock.unlock();        }    }    /**     * 当结余 >= k 时,结余 -= k     *     * @param k     */    public void withdraw(int k, int style) {        lock.lock();        try {            if (style == NORMAL) {                //preferRequests>0 表示有优先的取款在等待,则普通取款不能进行下去                while (surplus < k || preferRequests > 0) {                    condition.await();                }                surplus -= k;                System.out.println("Normale Thread " + Thread.currentThread().getName() + " withdraw "+ k);            } else if (style == PREFER) {                ++preferRequests;                while (surplus < k) {                    condition.await();                }                surplus -= k;                --preferRequests;                System.out.println("Prefer Thread " + Thread.currentThread().getName() + " withdraw "+ k);                condition.signalAll();            } else {                throw new InterruptedException();            }        } catch (InterruptedException e) {            e.printStackTrace();            condition.signalAll();        } finally {            lock.unlock();        }    }    /**     * 向另一个账户转账     * @param k 转账金额     * @param reserve     */    public void transfer(int k,Account reserve){        lock.lock();        try {            reserve.withdraw(k,NORMAL);            deposit(k);        }finally {            lock.unlock();        }    }}



private static void test_account() {        Account[] accounts = new Account[2];        for (int i = 0; i < accounts.length; ++i) {            accounts[i] = new Account();        }        TestAccountThread tester1 = new TestAccountThread(accounts[0], accounts[1]);        TestAccountThread tester2 = new TestAccountThread(accounts[1], accounts[0]);        tester1.start();        tester2.start();        try {            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("After sleep ");        for (Account account : accounts) {            account.deposit(1000);        }    }


(3)不一定全部会返回,因为可能在其他线程condition上死锁,boss notify自己的锁线程感应不到。


测试结果:

线程tester1tester2转账均失败,出现死锁




0 0
原创粉丝点击