黑马程序员技术交流社区

标题: 游乐园售票过程模拟(毕老师售票例子终极升级版) [打印本页]

作者: as604049322    时间: 2014-12-24 12:56
标题: 游乐园售票过程模拟(毕老师售票例子终极升级版)
本帖最后由 as604049322 于 2014-12-24 16:10 编辑

需求分析:
有一个游乐场,产票中心共有N张票,每张票有一个独一的编号(每张票用集合的一个元素表示)
每个售票窗口最大能装200张票,会在启动前从产票中心补满
售票窗口有上班和下班的操作,
下班有2种情况,票卖完或者公司统一下班
每次上班前都会检查当前的窗口的票是否为空,不为空直接上班,为空则从产票中心补满。
每个售票窗口工作人员为一人,一旦上班便开始卖票,每卖一张票打印买票人信息
买票人信息为电脑生成的随机人物
-------------------------------------------------------------
代码经过三次重写,现在测试,暂时没有发现问题。望马友友多多指证改进


  1. import java.util.LinkedList;
  2. class SaleTicket
  3. {
  4.     public static void main(String[] args)
  5.     {
  6.         Ticket t=Ticket.getInstanceof();
  7.         SaleTicketWindow s1=new SaleTicketWindow("售票窗口1");
  8.         SaleTicketWindow s2=new SaleTicketWindow("售票窗口2");
  9.         SaleTicketWindow s3=new SaleTicketWindow("售票窗口3");
  10.         SaleTicketWindow s4=new SaleTicketWindow("售票窗口4");
  11.         int num=0;
  12.         while(num<20){
  13.             s1.goWork();
  14.             s2.goWork();
  15.             s3.goWork();
  16.             s4.goWork();
  17.             try{Thread.sleep(5000);}catch(Exception e){}//每隔5秒钟就集体下班
  18.             s1.afterWork();
  19.             s2.afterWork();
  20.             s3.afterWork();
  21.             s4.afterWork();
  22.             try{Thread.sleep(5000);}catch(Exception e){}//5秒钟后再集体下班
  23.             num++;
  24.         }
  25.     }
  26. }

  27. class Ticket//产票中心
  28. {
  29.     private LinkedList<Integer> tickList=new LinkedList<Integer>();
  30.     private final int START_NUM=700001;//票的起始编号为3001
  31.     private final int TOTAL=5000;//产票中心总共生产5000张票
  32.     //单例设计模式
  33.     private static final Ticket t=new Ticket();
  34.     private Ticket(){//初始化产票中心
  35.         for(int i=START_NUM;i<START_NUM+TOTAL;i++)
  36.             tickList.add(i);
  37.     }
  38.     public static Ticket getInstanceof(){
  39.         return t;
  40.     }
  41.     public synchronized void printListre(){
  42.         if(isTickNoNull())
  43.             System.out.print(tickList);//打印产票中心剩下的票
  44.     }
  45.     public synchronized boolean isTickNoNull(){
  46.         if(tickList.size()>0)
  47.             return true;
  48.         else
  49.             return false;
  50.     }

  51.     public synchronized LinkedList<Integer> getTicket(int num){//num代表获取的票的数量
  52.         LinkedList<Integer> result=new LinkedList<Integer>();
  53.         for(int i=0;i<num;i++)
  54.             if(isTickNoNull())
  55.                 result.add(tickList.removeFirst());
  56.         return result;
  57.     }
  58. }

  59. class SaleTicketWindow//售票窗口
  60. {
  61.     private static final Ticket t=Ticket.getInstanceof();
  62.     private static final int MAX_TICKET=50;//每个售票窗口最多放200张票
  63.     private LinkedList<Integer> tickWin=new LinkedList<Integer>();//当前窗口的票
  64.     boolean flag=false;//售票状态
  65.     String name;//窗口名字
  66.     SaleTicketWindow(String name){
  67.         this.name=name;
  68.     }
  69.     class Run implements Runnable{
  70.         public void run(){
  71.             while(flag)
  72.                 sale();
  73.         }
  74.     }

  75.     public synchronized void sale(){
  76.         if(tickWin.size()>0){
  77.             try{Thread.sleep(100);}catch(Exception e){}
  78.             int number=tickWin.removeLast();
  79.             System.out.println(Thread.currentThread().getName()+":编号为"+number+"的票被卖出!信息:");
  80.             System.out.println("姓名:"+creatRandomName());
  81.             String sex=creatRandomSex();
  82.             System.out.println("性别:"+sex);
  83.             System.out.println("身份证号:"+creatRandomIDCard(sex));
  84.             System.out.println("编号:"+getNumber(number));
  85.         }else{
  86.             afterWork();
  87.         }
  88.     }
  89.     public void goWork(){//上班
  90.         if(flag==false){
  91.             if(tickWin.size()==0)
  92.                 tickWin=t.getTicket(MAX_TICKET);
  93.             flag=true;
  94.             new Thread(new Run(),name).start();
  95.         }
  96.     }
  97.     public void afterWork(){//下班
  98.         flag=false;
  99.     }

  100.     public static String creatRandomSex(){
  101.         if((int)(Math.random()*2)==1)
  102.             return "男";
  103.         else
  104.             return "女";
  105.     }

  106.     public static String creatRandomName(){
  107.         String[] firstName={"王","李","张","刘", "陈","杨","黄","赵", "周","吴","徐","孙", "马","胡","朱","郭", "何","罗","高","林",
  108.                             "郑","梁","谢","唐", "许","冯","宋","韩", "邓","彭","曹","曾", "田","于","肖","潘", "袁","董","叶","杜",
  109.                             "丁","蒋","程","余", "吕","魏","蔡","苏", "任","卢","沈","姜", "姚","钟","崔","陆", "谭","汪","石","付",
  110.                             "贾","范","金","方", "韦","夏","廖","侯", "白","孟","邹","秦", "尹","江","熊","薛", "邱","闫","段","雷",
  111.                             "季","史","陶","毛", "贺","龙","万","顾", "关","郝","孔","向", "龚","邵","钱","武", "扬","黎","汤","戴",
  112.                             "严","文","常","牛", "莫","洪","米","康", "温","代","赖","施"};
  113.         if((int)(Math.random()*2)==0)
  114.             return firstName[(int)(Math.random()*112)]+(char)(Math.random()*10000+21834);
  115.         else
  116.             return firstName[(int)(Math.random()*112)]+(char)(Math.random()*10000+21834)+(char)(Math.random()*10000+21834);
  117.     }
  118. /*
  119. (1)前1、2位数字表示:所在省份的代码;
  120. 身份证号与省份的关系 11 北京市;12 天津市;13 河北省;14 山西省;15 内蒙古自治区;21 辽宁省;22 吉林省;23 黑龙江省;31 上海市;32 江苏省;33 浙江省;
  121. 34 安徽省;35 福建省;36 江西省;37 山东省;41 河南省;42 湖北省;43 湖南省;44 广东省;45 广西壮族自治区;46 海南省;50 重庆市;51 四川省;52 贵州省;
  122. 53 云南省;54 西藏自治区;61 陕西省;62 甘肃省;63 青海省;64 宁夏回族自治区;65 新疆维吾尔自治区;71 台湾省;81 香港特别行政区;82 澳门特别行政区
  123. (2)第3、4位数字表示:所在城市的代码;
  124. (3)第5、6位数字表示:所在区县的代码;
  125. (4)第7~14位数字表示:出生年、月、日;
  126. (5)第15、16位数字表示:所在地的派出所的代码;
  127. (6)第17位数字表示性别:奇数表示男性,偶数表示女性;
  128. 第十八位数字的计算方法为:
  129. 1.将前面的身份证号码17位数分别乘以不同的系数。
  130.   从第一位到第十七位的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
  131. 2.将这17位数字和系数相乘的结果相加。
  132. 3.用加出来和除以11,看余数是多少?
  133. 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。
  134. 其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3 2。
  135.     */
  136.     public static String creatRandomIDCard(String man){
  137.         String IDCard="";
  138.         int[] province={11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82};
  139.         int temp=province[(int)(Math.random()*province.length)];//省代码
  140.         IDCard+=temp;
  141.         temp=getRandomNum(1,22);//市代码,没搞不清楚,随机生成1~22.
  142.         IDCard+=addNum(temp);
  143.         temp=getRandomNum(1,30);//市代码,没搞不清楚,随机生成1~30.
  144.         IDCard+=addNum(temp);
  145.         temp=getRandomNum(1900,2005);//出生年份为1900~2005年
  146.         IDCard+=temp;
  147.         temp=getRandomNum(1,12);//月份1~12
  148.         IDCard+=addNum(temp);
  149.         temp=getRandomNum(1,30);//日1~30.
  150.         IDCard+=addNum(temp);
  151.         temp=getRandomNum(1,92);//所在地的派出所的代码,没搞不清楚,随机生成1~92.
  152.         IDCard+=addNum(temp);
  153.         if(man=="男")
  154.             temp=(((int)(Math.random()*5))<<1)+1;
  155.         else
  156.             temp=((int)(Math.random()*5))<<1;
  157.         IDCard+=temp;
  158.         
  159.         int[] expon=new int[]{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
  160.         String[] checkSheet=new String[]{"1","0","X","9","8","7","6","5","4","3","2"};
  161.         int sum=0;
  162.         for(int i=0;i<expon.length;i++)
  163.             sum+=new Integer(IDCard.charAt(i))*expon[i];
  164.         IDCard+=checkSheet[sum%11];
  165.         return IDCard;
  166.     }
  167.     private static String addNum(int num){
  168.         if(num<10)
  169.             return "0"+num;
  170.         else
  171.             return num+"";
  172.     }
  173.     private static int getRandomNum(int start,int end){
  174.         return (int)(Math.random()*(end-start+1))+start;
  175.     }
  176.     private String getNumber(int num){
  177.         String result=Integer.toHexString(num).toUpperCase();
  178.         while(result.length()<8)
  179.             result="0"+result;
  180.         return result;
  181.     }
  182. }
复制代码






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