蓝色字体是考试题目:
预备知识:.生产者-消费者模式。在通信软件开发中,经常涉及到消息的处理,实现时会采用生产者-消费者模式:在同一个进程地址空间内执行的两个线程。
生产者线程产生消息,然后将消息放置在一个缓冲区内中供消费者线程处理。
消费者线程从缓冲区中读取消息进行处理。
当生产者线程产生消息时,如果缓冲区满,那么生产者线程必须等待消费者线程处理完消息以释放缓冲区,当消费者线程在读取消息进行处理时,如果缓冲区中没有消息,那么消费者线程将被阻塞,直到有消息被生产出来。
题目:
以银行存款和取款为背景,存款(生产)清单为add.txt,取款(消费)清单为take.txt。
add.txt格式如下:
Max:1000
List:100,300,800,500,400,200,600,700
take.txt格式如下:
Min:100
List:300,800,500,400,100,700,600,300
说明:
Max表示帐户的最大余额;Min表示帐户的最小余额;List表示存、取款的顺序清单。
要求:
命令行使用接口:
java BankOperation文件名 “BankOperation”参数是你将要实现的主程序类名,
该类有main方法public static void main(String [] args),是程序的入口。
控制台输出:
输出存取款的过程清单(List)和余额(Balance,不足时为负数),格式如下:
List:add100,add300,take300,add800。。。。。。。。。。。。
Balance:-200
提示:
余额说明:
当存款操作已经全部结束,取款出现不足时,余额为负数(所缺金额的总和,不要漏算帐户的最小余额)。
我对题目的要求的理解为:存钱时有上限,若超过上限,让给取钱线程运行。
取钱时有下限,如果超过下限让存钱线程运行。
但若存钱线程全部运行结束了,那么取钱线程就没有下限了,可以取到负数。
最后的正确答案应该是-100。
下面是我写的代码,但有点bug,有时运行程序会停住,导致最后一次的扣钱没有成功。不知道错在哪里?请各位帮忙看看吧,我的脑容量着实不够用了。
- Java code
package com.soko.quiz;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(); } 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); } 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(); } } } }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(); } } } }