Art of Multiprocessor Programming 答案 ch8

93.

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();
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值