package day15.Thread; class Tickets { //用单例设计模式写的 一个票 票只有100张 初始化后票不能新建对象 private static Tickets tick = null; private static int total ; public static int getTotal() { return total; } public static void setTotal(int total) { Tickets.total = total; } private Tickets() { total = 1000; } public static Tickets getSingleTickets() { if(tick == null)//加这部是为了效率高 因为大部分是不用判断锁的 { // 1a--> 挂这 // 2b--> 挂这 // 3a 活了 拿锁 synchronized(Tickets.class) { // 4 a-->挂这 // 5 b-->挂这? no b进不来 // 7 b进来了 这时已经tick不为 null了 灰溜溜出去; // if(tick == null) tick = new Tickets(); 6 a执行完了 tick不为null } } return tick; } }; class SellTick implements Runnable{ Tickets tick = null; SellTick() { tick = Tickets.getSingleTickets(); } @Override public void run() { while(true) { // if(Tickets.getTotal()<=0)//可写可不写 优化效率不高 写了反而觉得效率低了 // break; // --> /* * 为了防止出现-1 -2 */ // p synchronized(Tickets.class) { //判断是否为卖完 卖完了 则退出 没卖完 则继续卖 //写在里面和写在外面的区别显而易见 写在外面 可能买到最后一张 abcd四个窗口 都是返回true 都执行到p这个位置等待 //然后 a窗口把 最后一张票卖掉了 bcd 还继续进入拿锁 (假如下面这个判断移到上面去的话)并开始卖 -1 -2 -3 if(Tickets.getTotal()<=0) break; Tickets.setTotal(Tickets.getTotal()-1); System.out.println(Thread.currentThread().getName()+" 卖了 一张票 总余票还有 "+Tickets.getTotal()); } try { Thread.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class TestTickets { /**实现一个卖票程序 * 总共有100 张票 3个窗口同时卖票 不能出现卖出的票大于100张 * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SellTick a = new SellTick(); Thread t1 = new Thread(a,"窗口 a "); t1.start(); new Thread(new SellTick(),"窗口 b").start(); new Thread(new SellTick(),"窗口 c").start(); new Thread(new SellTick(),"窗口 d").start(); } }
多线程卖票 单例设计模式 懒汉式
最新推荐文章于 2022-07-20 14:47:07 发布