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();
}
}
多线程卖票 单例设计模式 懒汉式
最新推荐文章于 2024-01-21 21:20:42 发布
