日期:2014-05-20  浏览次数:20649 次

关于线程同步的。。。看看错在哪

Java code

/*我这明明只有14张票,却卖掉了15张,才提示售票结束
期望的答案的是卖到第15个人的时候告诉他,票已售完。再结束
错在哪呢?*/
class SalesLady {
    int memontoes, five, ten;

    public synchronized String ruleForSale(int num, int money) {
        String s = null;
        if (memontoes == 0)
            return "对不起,已经售完";
        if (money == 5) {
            memontoes--;
            five++;
            s = "给你票," + "你的钱正好。";
        } else if (money == 10) {
            while (five < 1) {
                try {
                    System.out.println("" + num + "号顾客用10元购票,请等待");
                    wait();
                } catch (InterruptedException e) {
                }
            }
            memontoes--;
            five -= 1;
            ten++;
            s = "给你票," + "找你5元。";
        }
        notifyAll();
        return s;
    }

    SalesLady(int m, int f, int t) {
        memontoes = m;
        five = f;
        ten = t;
    }
}

public class 八_5 extends java.applet.Applet {
    static SalesLady saleslady = new SalesLady(14, 0, 0);
    public void start() {
        int moneies[] = { 10, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 5, 10, 5};
        Thread[] aThreadArray = new Thread[20];
        System.out.println("现在开始售票:");
        for (int i = 0; i < moneies.length; i++) {
            aThreadArray[i] = new Thread(new CustomerClass(i + 1, moneies[i]));
            aThreadArray[i].start();
        }
        WhileLoop: while (true) {
            for (int i = 0; i < moneies.length; i++)
                if (aThreadArray[i].isAlive())
                    continue WhileLoop;
            break;
        }
        System.out.println("票已售完");
    }
}

class CustomerClass implements Runnable {
    int num, money;

    public void run() {
        try {
            Thread.sleep(10);
        } 
        catch (InterruptedException e) {
        }
        System.out.println("我是" + num + "号顾客,用" + money + "元购票,售票员说:"
                + 八_5.saleslady.ruleForSale(num, money));
    }

    CustomerClass(int n, int m) {
        num = n;
        money = m;
    }
}


------解决方案--------------------
Java code
      while (five < 1) {
        try {
          System.out.println("" + num + "号顾客用10元购票,请等待");
          wait();
        } catch (InterruptedException e) {}
      }
      if (memontoes <= 0) {
        return "对不起,已经售完";
      }

------解决方案--------------------
System.out.println("我是" + num + "号顾客,用" + money + "元购票,售票员说:"
+ 八_5.saleslady.ruleForSale(num, money));

经过测试发现LZ的问题所在是上面这条语句。由于打印出这段话也需要时间,导致LZ看到的打印结果不是按照顺序列出的。
调试发现,调用八_5.saleslady.ruleForSale(num, money)方法后已经释放了锁,其它线程马上进入,从而出现后进入线程比执行完同步方法准备打印的线程更快的打印出结果了。
------解决方案--------------------
我是说55楼正解,给打印语句加个锁。