A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 不喝茶的陆羽 于 2013-6-7 23:46 编辑

class Ticket{
        private static int ticketNum;

        public int getTicketNum() {
                return ticketNum;
        }

        public Ticket(int ticketNum){
                this.ticketNum=ticketNum;
        }
        public static  boolean available(){
                if(ticketNum>0){
                        return true;
                }
                else{
                        return false;
                }
        }
        public static  void sealTicket(String winName){               
                        System.out.println(winName+"-----恭喜您,您已完成票务购买-----");
                        System.out.println("还剩余"+(--ticketNum)+"张票");               
        }
}
class SealWindow implements Runnable {
        private String winName;
        private Ticket ticket;

        SealWindow(String winName,Ticket ticket){
                this.winName=winName;
                this.ticket=ticket;
        }
        public void run(){
                System.out.println("欢迎来到"+winName+"售票窗口,很高兴为您服务");
                synchronized(ticket){
                while(ticket.available()){
                                Ticket.sealTicket(winName);
                        }                                       
                }
                System.out.println("-----票已卖完,下次发售时间:明早8:00,欢迎届时购买-----");        
        }         
}        
public class Test7 {   //此处的Test7应该为TicketSealCenter,但是因为考试要求中的类名规范,特此说明

        public static void main(String[] args) {
                //售票中心 分配售票窗口 和总票数
                // 生产票 送到售票中心
                Ticket ticket = new Ticket(1000);
                //建立 3个售票窗口
                SealWindow sw1 = new SealWindow("售票窗口一",ticket);
                SealWindow sw2 = new SealWindow("售票窗口二",ticket);
                SealWindow sw3 = new SealWindow("售票窗口三",ticket);
               
                new Thread(sw2).start();
                new Thread(sw1).start();
                new Thread(sw3).start();
        }
}
急等各位大神回复啊~

24 个回复

正序浏览
神之梦 发表于 2013-6-7 23:52
没事,我回帖一是希望可以帮助哥们,二是巩固自己的知识,对于金币或者技术分都无所谓了(确实我已经满了 ...

希望学长或是学姐有时间的话能解答下我的这个问题,麻烦了~
http://bbs.itheima.com/thread-55111-1-1.html
回复 使用道具 举报
曹宇 发表于 2013-6-8 16:53
不是的。。

whie(true)

对,我和continue混了
回复 使用道具 举报
不喝茶的陆羽 发表于 2013-6-8 13:33
疑问就是while(true){
            break;
}是死循环吗?

不是的。。

whie(true)
{

}

这样是死循环

while(true)
{
  循环中加入判断 如果什么什么的  就 break;
  break;就是跳出循环结束循环的语句。
}
回复 使用道具 举报
曹宇 发表于 2013-6-8 12:12
不会把,我刚又试了一次,
我把你发问题的源代码复制进编辑器,又把修改的while循环覆盖原代码的循环
不 ...

有一个新问题,如果有时间,希望能解答下~http://bbs.itheima.com/thread-55111-1-1.html
回复 使用道具 举报
疑问就是while(true){
            break;
}是死循环吗?
回复 使用道具 举报
曹宇 发表于 2013-6-8 12:12
不会把,我刚又试了一次,
我把你发问题的源代码复制进编辑器,又把修改的while循环覆盖原代码的循环
不 ...

这个循环,你不是把判断值设为true了吗?那又怎么会卖完就退出呢?
回复 使用道具 举报
不喝茶的陆羽 发表于 2013-6-8 02:00
while(true)
                                {
                                                synch ...

不会把,我刚又试了一次,
我把你发问题的源代码复制进编辑器,又把修改的while循环覆盖原代码的循环
不会死循环阿,卖完就结束了.

从代码上分析,循环内部 第一步就判断 当卖完票后,判断不会满足 就会执行break 跳出的。。

你再看看你代码,是否有什么地方能够是的程序无法跳出循环

回复 使用道具 举报
while(true)
                                {
                                                synchronized(ticket)
                                                {
                                                        if(ticket.available())
                                                        {
                                                                Ticket.sealTicket(winName);
                                                               
                                                        }
                                                        else
                                                                break;
                        }                                       
                }
虽然结果出来了,但是线程还是在一直运作啊...一直在循环
回复 使用道具 举报
曹宇 发表于 2013-6-8 00:26
系统做好了,。。。。
在循环部分改成这样首先 同步移动到循环之内,这样才会让别的线程有机会

这个虽然解决了同步问题,但是不会造成死循环吗?虽然不满足循环里面代码但是它会一直转啊?
回复 使用道具 举报
曹宇 发表于 2013-6-8 00:32
一开始我以为搞错了 怎么还是一直一个线程在卖阿,我就蛋疼,怎么分析也没错,后来多运行几次,突然发现。
...

谢谢啦~辛苦了。
回复 使用道具 举报
曹宇 发表于 2013-6-8 00:32
一开始我以为搞错了 怎么还是一直一个线程在卖阿,我就蛋疼,怎么分析也没错,后来多运行几次,突然发现。
...

谢谢啦~辛苦了。
回复 使用道具 举报
一开始我以为搞错了 怎么还是一直一个线程在卖阿,我就蛋疼,怎么分析也没错,后来多运行几次,突然发现。

不对阿,

如果问题没解决只能一个线程在玩单机游戏,那凭什么会是 售票窗口1 在卖票呢。

因为我分析了一下你的主函数
  1. new Thread(sw2).start();
  2.                 new Thread(sw1).start();
  3.                 new Thread(sw3).start();
复制代码
你是先创建的线程2 就是售票窗口2  如果问题没解决那么永远是窗口2在玩单机游戏,凭什么1能卖盘,1只能等2卖完才能打印个 苦逼的票已经卖完。

然后 多运行了几次,发现了窗口1  立刻 ctrl+c  然后就发现了。
  1. 程序运行输出:

  2. 还剩余99989张票
  3. 售票窗口二-----恭喜您,您已完成票务购买-----
  4. 还剩余99988张票
  5. 售票窗口二-----恭喜您,您已完成票务购买-----
  6. 还剩余99987张票
  7. 售票窗口二-----恭喜您,您已完成票务购买-----
  8. 还剩余99986张票
  9. 售票窗口一-----恭喜您,您已完成票务购买-----
  10. 还剩余99985张票
  11. 售票窗口一-----恭喜您,您已完成票务购买-----
  12. 还剩余99984张票
  13. 售票窗口一-----恭喜您,您已完成票务购买-----
  14. 还剩余99983张票
  15. 售票窗口一-----恭喜您,您已完成票务购买-----
复制代码
总算让我逮到了。。。。

我还蛋疼的以为代码错误呢。。。。


好吧,可能是CPU运行速度过快,或者过慢?

回复 使用道具 举报
系统做好了,。。。。
在循环部分改成这样
  1. while(true)
  2.                                 {
  3.                                                 synchronized(ticket)
  4.                                                 {
  5.                                                         if(ticket.available())
  6.                                                         {
  7.                                                                 Ticket.sealTicket(winName);
  8.                                                                
  9.                                                         }
  10.                                                         else
  11.                                                                 break;
  12.                         }                                       
  13.                 }
复制代码
首先 同步移动到循环之内,这样才会让别的线程有机会

判断也要在同步之内判断。

因为在同步外判断,当一个线程判断票数为1  好的 满足,然后还没进去同步 另外一个线程抢了CPU然后判断 哟 是1阿 满足,然后 它进去了,它卖完了
释放CPU  然后那个被抢的悲催线程获得了执行权  

因为他判断过了 是1满足 所以直接就进去了,所以就会打印出  票卖完  剩余票数 -1     -1阿-1阿-1阿 ,  哪个火车站敢这样打印出来,还不叫人拍照发送到糗事百科上去给人乐阿。。

所以 判断要在同步内判断,也就是说每一个进入同步的线程 都先判断 满足在搞  不满足直接break 没票了,哥们你逃票得了。。
回复 使用道具 举报
不喝茶的陆羽 发表于 2013-6-7 23:45
抱歉,我才 知道,最多只能给30分,不好意思了....

没事,我回帖一是希望可以帮助哥们,二是巩固自己的知识,对于金币或者技术分都无所谓了(确实我已经满了-_-||),三是通过交流可以多认识些朋友,同时也传达一种乐于去帮助别人解决问题的精神(无关技术分而为之的)
回复 使用道具 举报
曹宇 发表于 2013-6-7 23:37
首先,我如果你老师 这题满分100就算你写对了 我也会只给你80分。

写代码,并且是发代码寻求帮助,最基本 ...

谢谢你的建议
回复 使用道具 举报
神之梦 发表于 2013-6-7 23:28
同步加在while里面
还有一点就是:
available方法没必要,虽然不影响结果,但是尽量简化代码 ...

抱歉,我才 知道,最多只能给30分,不好意思了....
回复 使用道具 举报
  1. synchronized(ticket){
  2.                 while(ticket.available()){
  3.                                 Ticket.sealTicket(winName);
  4.                         }                                       
  5.                 }
复制代码
注意这一段代码。

while循环判断票数是否为0 有票就继续卖。

那么 如果线程1 先执行 那么线程1 在卖票 因为你加入的有同步锁 所以其他线程根本就进不来,只能眼巴巴的看着线程1 一直将票卖完  然后线程1循环结束

这时候其他线程才能进入同步锁执行,而当它们进入的时候,就傻眼了 ,因为线程1这个混蛋已经全部把票卖完了,所以

你的程序最后总有3句  票已经卖完 请下次再买。。

问题就出在这里,解决方案你自己想一想,我要继续给电脑做系统了。。。等会做完系统后在来看看,要是不知道的话在回复问我把。
回复 使用道具 举报
神之梦 发表于 2013-6-7 23:28
同步加在while里面
还有一点就是:
available方法没必要,虽然不影响结果,但是尽量简化代码 ...

谢谢,虽然说得很简练,但是还是履行我的承诺
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马