黑马程序员技术交流社区

标题: 卖票问题,用三个类的咋做不出来了呢? [打印本页]

作者: 微小山    时间: 2014-12-19 10:01
标题: 卖票问题,用三个类的咋做不出来了呢?
编写三各类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。 关于这个题,用一个Ticket类做得出来,用三个类咋做不出来了呢?
作者: 染指青春    时间: 2014-12-19 10:13
哥们。。。实在想不出来百度一下,可以搜到的。不过自己不跟着多敲几遍记不住
作者: 襄王有梦    时间: 2014-12-19 10:52
把你做的代码发一下,大家一起看看怎么解决
作者: wuyuwen    时间: 2014-12-19 11:00
我是来学习的
作者: 微小山    时间: 2014-12-19 11:23
染指青春 发表于 2014-12-19 10:13
哥们。。。实在想不出来百度一下,可以搜到的。不过自己不跟着多敲几遍记不住 ...

呵呵,俺是女汉子滴说!;P
作者: 染指青春    时间: 2014-12-19 11:27
微小山 发表于 2014-12-19 11:23
呵呵,俺是女汉子滴说!

呃呃呃。。。好吧,女汉子不容易啊。加油!!{:3_53:}
作者: junge520    时间: 2014-12-19 11:30
这个应该是很简单的吧···
作者: abathe    时间: 2014-12-19 11:42
好人一生平安

作者: Quasimodo    时间: 2014-12-19 12:34
  1. public class Test13 {
  2.         /**
  3.          * 编写三各类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。售票中心分配一定数量的票,
  4.          * 由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。
  5.          *
  6.          * 多个售票窗口一起工作,这是一个多线程考题
  7.          */

  8.         public static void main(String[] args) {
  9.                 // 新建一个售票中心
  10.                 TicketSealCenter center = new TicketSealCenter();
  11.                 // 设置好车票出发和目的地,这时候票信息中还没有座位号
  12.                 center.setTicket("广州", "南宁");
  13.                 // 分配票的数量
  14.                 center.setAmount(1000);

  15.                 // 创建一个售票中心 实现Runnable 在run方法中会给加上座位号 然后打印
  16.                 SealWindow seal = new SealWindow(center.getTicket(), center.getAmount());
  17.                 // 创建线程并执行
  18.                 Thread t1 = new Thread(seal, "一号窗");
  19.                 Thread t2 = new Thread(seal, "二号窗");
  20.                 Thread t3 = new Thread(seal, "三号窗");
  21.                 t1.start();
  22.                 t2.start();
  23.                 t3.start();

  24.         }

  25. }

  26. class Ticket {
  27.         // 票的属性有座位号跟出发目的地
  28.         private int num;
  29.         private String off;
  30.         private String des;

  31.         // 有参构造(参数中不含座位号) 以便让售票中心初始化
  32.         public Ticket(String off, String des) {
  33.                 this.off = off;
  34.                 this.des = des;
  35.         }

  36.         // 设置座位号让售票窗口打印设置好的票
  37.         public void setNum(int num) {
  38.                 this.num = num;
  39.         }

  40.         // 票信息
  41.         public String toString() {
  42.                 return off + "------>"  + des + "\r\n" + "座位号" + num;
  43.         }

  44. }

  45. class SealWindow implements Runnable {
  46.         private int amount;
  47.         private Ticket ticket;

  48.         // 有参构造 传入的是要卖的票的信息 还有 一共可以卖多少张票
  49.         public SealWindow(Ticket ticket, int amount) {
  50.                 this.ticket = ticket;
  51.                 this.amount = amount;
  52.         }

  53.         public void run() {
  54.                 while (true) {
  55.                         synchronized (this) {
  56.                                 if (amount > 0) {
  57.                                         try {
  58.                                                 Thread.sleep(2);
  59.                                         } catch (InterruptedException e) {
  60.                                         }
  61.                                         // 这里就是设置票的座位号 设置好 打印
  62.                                         ticket.setNum(amount--);
  63.                                         System.out
  64.                                                         .println(Thread.currentThread().getName() + "售出:");
  65.                                         System.out.println(ticket.toString());
  66.                                         System.out.println();
  67.                                 } else {
  68.                                         System.out.println("无票可售");
  69.                                         break;
  70.                                 }
  71.                         }
  72.                 }
  73.         }
  74. }

  75. // 售票中心
  76. class TicketSealCenter {
  77.         private int amount;
  78.         private Ticket ticke;
  79.         //设置总票数
  80.         public void setAmount(int amount) {
  81.                 this.amount = amount;
  82.         }

  83.         // 分配可以售出的总票数
  84.         public int getAmount() {
  85.                 return amount;
  86.         }
  87.         //设置票信息的出发地和目的地(不含座位号)
  88.         public void setTicket(String off, String des) {
  89.                 ticke = new Ticket(off, des);
  90.         }

  91.         //返回票信息(还不含座位号)
  92.         public Ticket getTicket() {
  93.                 return ticke;
  94.         }
  95. }
复制代码


这是我写的,希望可以参考一下,不知道这样算不算对得上题意
作者: Rain2692    时间: 2014-12-19 14:46
微小山 发表于 2014-12-19 11:23
呵呵,俺是女汉子滴说!

:(:(啊啊啊啊
作者: 后悔药    时间: 2014-12-19 15:20
早上不知道是不是回的这个帖子,当时理解错误,重新敲了一遍,就是老毕的多线程消费者与生产者,这里操作资源当做票的集合就行了。下面是我的代码,我在售票的时候加了休眠,不然每次都是同一个线程把售票中心生产的票给卖完了
  1. public class Test4 {

  2.         public static void main(String[] args) {

  3.                 Ticket ticket = new Ticket("芜湖", 0);
  4.                 TicketSealCenter tsc1 = new TicketSealCenter(ticket);
  5.                 SealWindow sw1 = new SealWindow(ticket);
  6.                 SealWindow sw2 = new SealWindow(ticket);
  7.                 SealWindow sw3 = new SealWindow(ticket);
  8.                 // SealWindow sw4 = new SealWindow(ticket);

  9.                 Thread th1 = new Thread(tsc1);
  10.                 th1.setName("售票中心");
  11.                 Thread th2 = new Thread(sw2);
  12.                 th2.setName("售票窗口1");
  13.                 Thread th3 = new Thread(sw1);
  14.                 th3.setName("售票窗口2");
  15.                 Thread th4 = new Thread(sw3);
  16.                 th4.setName("售票窗口3");

  17.                 th1.start();
  18.                 th2.start();
  19.                 th3.start();
  20.                 th4.start();
  21.         }

  22. }

  23. class SealWindow implements Runnable {

  24.         private Ticket ticket;

  25.         public SealWindow(Ticket ticket) {
  26.                 this.ticket = ticket;
  27.         }

  28.         @Override
  29.         public void run() {

  30.                 while (true) {
  31.                         ticket.seal();
  32.                        
  33.                         try {
  34.                                 Thread.sleep(500);
  35.                         } catch (InterruptedException e) {
  36.                                 // TODO Auto-generated catch block
  37.                                 e.printStackTrace();
  38.                         }
  39.                 }
  40.         }
  41. }

  42. class TicketSealCenter implements Runnable {

  43.         private Ticket t;

  44.         public TicketSealCenter(Ticket t) {
  45.                 this.t = t;
  46.         }

  47.         @Override
  48.         public void run() {

  49.                 while (true) {
  50.                         // 生产芜湖车次的车票
  51.                         t.pro("芜湖");
  52.                 }
  53.         }

  54. }

  55. class Ticket {

  56.         static LinkedList<Ticket> pool = new LinkedList<Ticket>();

  57.         private String destination;
  58.         private int site = 0;

  59.         public Ticket(String destination, int site) {
  60.                 this.destination = destination;
  61.                 this.site = site;
  62.         }

  63.         private boolean flag = false;

  64.         private Lock lock = new ReentrantLock();
  65.         private Condition con_pro = lock.newCondition();
  66.         private Condition con_seal = lock.newCondition();

  67.         public void pro(String des) {
  68.                 lock.lock();
  69.                 try {
  70.                         while (flag) {
  71.                                 con_pro.await();
  72.                         }
  73.                         //每次生产若干票
  74.                         int num = (int) (Math.random() * 10)+1;
  75.                         for (int i = 0; i < num; i++) {
  76.                                 Ticket t = new Ticket(des, site++);
  77.                                 pool.addFirst(t);
  78.                                 System.out.println(Thread.currentThread().getName() + "生产了"
  79.                                                 + t.toString());
  80.                         }

  81.                         flag = true;
  82.                         con_seal.signal();

  83.                 } catch (InterruptedException e) {
  84.                         e.printStackTrace();
  85.                 } finally {
  86.                         lock.unlock();
  87.                 }

  88.         }

  89.         /**
  90.          * 这个方法被若干线程操作
  91.          */
  92.         public void seal() {

  93.                 lock.lock();
  94.                 try {
  95.                         while (!flag) {
  96.                                 con_seal.await();
  97.                         }
  98.                        
  99.                         if (pool.size() > 0) {
  100.                                 // 如果有票,售票窗口就开始卖票并打印信息
  101.                                 System.out.println(Thread.currentThread().getName() + "售出了"
  102.                                                 + pool.removeLast().toString());
  103.                         } else {
  104.                                 // 如果没有有票,唤醒售票中心线程生产票
  105.                                 flag = false;
  106.                                 con_pro.signal();
  107.                         }
  108.                 } catch (InterruptedException e) {
  109.                         e.printStackTrace();
  110.                 }finally{
  111.                         lock.unlock();
  112.                 }
  113.         }

  114.         @Override
  115.         public String toString() {
  116.                 // destination车次第site座
  117.                 return destination + "车次第" + site + "座";
  118.         }

  119. }
复制代码

作者: 微小山    时间: 2014-12-19 16:10
后悔药 发表于 2014-12-19 15:20
早上不知道是不是回的这个帖子,当时理解错误,重新敲了一遍,就是老毕的多线程消费者与生产者,这里操作资 ...

嗯,看了一下打的蛮好的,女汉给你点32个赞。呵呵,在seal的地方是不是那个if可以改为while,让它把发布的票都拿走掉
作者: 后悔药    时间: 2014-12-19 16:47
微小山 发表于 2014-12-19 16:10
嗯,看了一下打的蛮好的,女汉给你点32个赞。呵呵,在seal的地方是不是那个if可以改为while,让它把发布 ...

你把那个500ms的休眠注解掉就可以了。程序运行的时候seal方法的外层已经有while循环了,我自己测试就是每次都是同一个线程刚解锁就又进入循环抢到锁,导致其他线程一直拿不到执行权,所以同一个线程把票抢完了,加了一个500ms休眠才解决。
作者: as604049322    时间: 2014-12-19 20:47
:(:(给你们的代码点赞:lol




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