二级我的答案

有点bug,有时程序会停住,导致最后一次的扣钱没有成功。
题目的要求是存钱时有上限,若超过上限,让给取钱线程运行。
取钱时有下限,如果超过下限让存钱线程运行。
但若存钱线程全部运行结束了,那么取钱线程就没有下限了,可以取到负数。
最后的答案应该是-100。

package com.jin.lv2;

public class BankOperation
{
	public static void main(String[] args) throws Exception
	{
		int[] addList = new int[]{100, 300, 800, 500, 400, 200, 600, 700};
		int[] takeList = new int[]{300, 800, 500, 400, 100, 700, 600, 300};
		
		Balance balance = new Balance();
		Thread adder = new Adder(balance, addList);
		Thread taker = new Taker(balance, takeList);
		
		System.out.print("List:");
		adder.start();
		taker.start();
		
		Thread.sleep(500);
		System.out.println("\nBalance:" + balance.getMoney()); //正确答案是 -100
	}
}

class Balance {
	
	private int money = 0;
	boolean isAddOver = false;
	
	public synchronized int getMoney()
	{
		return this.money;
	}
	
	public synchronized void add(int num) throws Exception
	{
		this.notifyAll();
		while((money + num) > 1000)
		{
			this.wait();
			//Thread.yield();  不能使用yield(),yield虽然停了,但不会释放锁,别人操作不了balance了
		} 
		
		money += num;
		
		System.out.print("add" + num + ", ");
System.out.println("balance:" + money);
	}
	
	public synchronized void take(int num) throws Exception
	{
		this.notifyAll();
		while((money - num) < 100 && !isAddOver)
		{		
			this.wait();
System.out.println("陷入循环无法跳出。 此时的money=" + money + "此时isAddOver=" + isAddOver);		
			//Thread.yield(); 不能使用yield(),yield虽然停了,但不会释放锁,别人操作不了balance了
			
		}
		money -= num;
		
		System.out.print("take" + num + ", ");
System.out.println("balance:" + money);
	}
	
}

class Adder extends Thread {
	
	private Balance balance;
	private int[] addList;
	public Adder(Balance balance, int[] addList)
	{
		this.balance = balance;
		this.addList = addList;
	}
	
	public void run()
	{
		for(int i=0; i<addList.length; i++)
		{
			try
			{
				balance.add(addList[i]);
			}
			catch (Exception e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//balance.isAddOver = true; 不是合适的地方,最好在添加结束后立刻就设为true,所以保证在同步方法add最后搞
	}
	
}

class Taker extends Thread {
	
	private Balance balance;
	private int[] takeList;
	public Taker(Balance balance, int[] takeList)
	{
		this.balance = balance;
		this.takeList = takeList;
	}
	
	public void run()
	{
		for(int i=0; i<takeList.length; i++)
		{
			try
			{
				balance.take(takeList[i]);
			}
			catch (Exception e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

你可能感兴趣的:(二级我的答案)