多线程卖票 单例设计模式 懒汉式

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();

	}

}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值