首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

java 线程同步题目,有点儿小疑点

2012-03-29 
java 线程同步题目,有点儿小问题。蓝色字体是考试题目:预备知识:.生产者-消费者模式。在通信软件开发中,经常

java 线程同步题目,有点儿小问题。
蓝色字体是考试题目:
预备知识:.生产者-消费者模式。在通信软件开发中,经常涉及到消息的处理,实现时会采用生产者-消费者模式:在同一个进程地址空间内执行的两个线程。
生产者线程产生消息,然后将消息放置在一个缓冲区内中供消费者线程处理。
消费者线程从缓冲区中读取消息进行处理。
当生产者线程产生消息时,如果缓冲区满,那么生产者线程必须等待消费者线程处理完消息以释放缓冲区,当消费者线程在读取消息进行处理时,如果缓冲区中没有消息,那么消费者线程将被阻塞,直到有消息被生产出来。
题目:
以银行存款和取款为背景,存款(生产)清单为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();            }        }    }    } 



[解决办法]
进行操作之后在唤醒线程
[解决办法]
要用线程唤醒。就是挂起
[解决办法]
我分析是两个问题:
1 isAddOver 的问题,程序中除了赋初值外,就再没被赋值了。

按意思应该在Adder类的run方法里,for循环结束应该加一句:
Java code
        balance.isAddOver=true; 

热点排行