黑马程序员技术交流社区

标题: 大神帮忙看看我这个程序哪里出问题了 [打印本页]

作者: 吐槽星人    时间: 2015-7-18 19:21
标题: 大神帮忙看看我这个程序哪里出问题了
这个题目我自己测试了多次,但老师说我的有问题。可能是因为我的结果显示的是每个窗口卖的票数。其实每个窗口卖的票数加起来就是总票数了。要改显示的话只需要改下打印部分而已。希望有大神能来解答下。
  1. /**
  2. * 8、 编写三个类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。
  3. * 售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。
  4. * @author Administrator
  5. *
  6. */
  7. public class Test8 {

  8.         public static void main(String[] args) {
  9.                 //建立一个TicketSealCenter对象,
  10.                 TicketSealCenter tsc=new TicketSealCenter();
  11.                 //调用方法传入100张票,4个窗口
  12.                 tsc.Method(100, 4);
  13.         }

  14. }
  15. class Ticket{
  16.         //定义一个变量存储票数
  17.          int ticketnums;
  18.         //定义一个变量控制是否有票
  19.          boolean flag=true;
  20.         //将票的数目传递进来
  21.         public Ticket(int ticketnums){
  22.                 this.ticketnums=ticketnums;
  23.         }
  24.        
  25.        
  26. }
  27. class SealWindow implements Runnable{
  28.         //定义一个票的对象
  29.         Ticket ticket;
  30.         //定义一个数记录当前窗口卖了多少票
  31.         int count;
  32.         //定义一个数存储传递进来的窗口号码
  33.         int number;
  34.         //将票的对象和窗口号码传递进来
  35.         public SealWindow(Ticket ticket,int number) {
  36.                 this.ticket=ticket;
  37.                 this.number=number;
  38.         }
  39.         @Override
  40.         public void run() {
  41.                 //如果有票则卖
  42.                 while(ticket.flag) {
  43.                         //定义一个锁
  44.                         synchronized (SealWindow.class) {
  45.                                 //当票数大于0时则卖一张票
  46.                                 if (ticket.ticketnums>0) {
  47.                                 count++;
  48.                                 System.out.println("第"+number+"号窗口卖了"+count+"张票");
  49.                                 ticket.ticketnums--;
  50.                                 }else {
  51.                                         //没票将flag赋值为false
  52.                                         ticket.flag=false;
  53.                                 }
  54.                                
  55.                         }
  56.                         //使当前线程睡眠0.1s,可以让我们更清楚的看到线程运行的结果
  57.                         try {
  58.                                 Thread.sleep(100);
  59.                         } catch (Exception e) {
  60.                                 e.printStackTrace();
  61.                         }
  62.                 }
  63.         }
  64. }
  65. class TicketSealCenter{
  66.         //将票的数量和窗口数量传递进来
  67.         public void Method(int ticketnums,int number) {
  68.                 //将票数传递给票类
  69.                 Ticket ticket=new Ticket(ticketnums);
  70.                 //创建number个线程
  71.                 for(int x=0;x<number;x++) {
  72.                         new Thread(new SealWindow(ticket, x)).start();
  73.                 }
  74.         }
  75. }
复制代码



作者: a12366456    时间: 2015-7-18 19:21
感觉你这个思路不太好,首先卖票的行为方法应该定义到票Ticket这个类中,数据和对数据的操作应该封装到一个类中,由于票的数量是几个售票窗口公用的数据,所以锁要加在Ticket类的售票方法上,售票窗口SealWindow类应该是多线程的,这个和你的一样,不过run方法中应该调用Ticket的售票方法进行售票,售票中心TicketSealCenter类应该是初始化票Ticket和开启一定数量的售票窗体线程。我的售票是从100号往下减的,可以改为从1号售票。
  1. package com.drz.ciancheng_shoupiao;

  2. /**
  3. * 8、 编写三个类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。
  4. * 售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。
  5. *
  6. * @author drzwin32
  7. *
  8. */
  9. public class Ticket {
  10.         private int ticNum;

  11.         public Ticket(int ticNum) {
  12.                 this.ticNum = ticNum;
  13.         }

  14.         public synchronized void sellTic(int windowId) {
  15.                 if (ticNum > 0) {

  16.                         System.out.println(windowId + "号窗口卖出" + ticNum + "号票");
  17.                         ticNum--;
  18.                 }
  19.         }

  20.         public Ticket() {
  21.                 // TODO Auto-generated constructor stub
  22.         }

  23.         public int getTicNum() {
  24.                 return ticNum;
  25.         }

  26.         public void setTicNum(int ticNum) {
  27.                 this.ticNum = ticNum;
  28.         }

  29. }
  30. //--------------------售票窗口
  31. package com.drz.ciancheng_shoupiao;

  32. public class SealWindow implements Runnable {
  33.         private Ticket ticket;
  34.         private int windowId;

  35.         public SealWindow(Ticket ticket, int windowId) {
  36.                 this.setTicket(ticket);
  37.                 this.windowId = windowId;
  38.         }

  39.         public SealWindow() {
  40.                 // TODO Auto-generated constructor stub
  41.         }

  42.         @Override
  43.         public void run() {
  44.                 while (ticket.getTicNum() > 0) {
  45.                         try {
  46.                                 Thread.sleep(1000);
  47.                         } catch (InterruptedException e) {
  48.                                 // TODO Auto-generated catch block
  49.                                 e.printStackTrace();
  50.                         }
  51.                         ticket.sellTic(windowId);
  52.                 }

  53.         }

  54.         public Ticket getTicket() {
  55.                 return ticket;
  56.         }

  57.         public void setTicket(Ticket ticket) {
  58.                 this.ticket = ticket;
  59.         }

  60.         public int getWindowId() {
  61.                 return windowId;
  62.         }

  63.         public void setWindowId(int windowId) {
  64.                 this.windowId = windowId;
  65.         }

  66. }
  67. //----------------售票中心
  68. package com.drz.ciancheng_shoupiao;

  69. public class TicketSealCenter {
  70.         private Ticket ticket;
  71.         private int winNum;

  72.         public TicketSealCenter(Ticket ticket, int winNum) {
  73.                 this.ticket = ticket;
  74.                 this.winNum = winNum;
  75.                 for (int i = 1; i <= winNum; i++) {
  76.                         new Thread(new SealWindow(ticket, i)).start();
  77.                 }
  78.         }

  79.         public TicketSealCenter() {
  80.                 // TODO Auto-generated constructor stub
  81.         }

  82.         public Ticket getTicket() {
  83.                 return ticket;
  84.         }

  85.         public void setTicket(Ticket ticket) {
  86.                 this.ticket = ticket;
  87.         }

  88.         public int getWinNum() {
  89.                 return winNum;
  90.         }

  91.         public void setWinNum(int winNum) {
  92.                 this.winNum = winNum;
  93.         }

  94. }
  95. //---------------------启动代码
  96. package com.drz.ciancheng_shoupiao;

  97. public class Run {

  98.         public Run() {
  99.                 // TODO Auto-generated constructor stub
  100.         }

  101.         /**
  102.          * 8、 编写三个类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。
  103.          * 售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。
  104.          *
  105.          * @param args
  106.          */
  107.         public static void main(String[] args) {
  108.                 Ticket ticket=new Ticket(100);
  109.                 new TicketSealCenter(ticket, 4);
  110.         }

  111. }
复制代码

作者: 吐槽星人    时间: 2015-7-18 21:36
a12366456 发表于 2015-7-18 21:35
感觉你这个思路不太好,首先卖票的行为方法应该定义到票Ticket这个类中,数据和对数据的操作应该封装到一个 ...

可是我的程序运行起来结果没问题不是么
作者: a12366456    时间: 2015-7-18 21:49
吐槽星人 发表于 2015-7-18 21:36
可是我的程序运行起来结果没问题不是么

我没运行你的代码,我看了运行结果应该没问题
作者: JOKER0819    时间: 2015-8-19 22:48
都是紧密的逻辑关系啊!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2