多线程-买电影票出现了同票和负数票的原因分析

本文介绍了一个基于Java的多线程售票系统实现案例。通过创建三个线程模拟售票窗口,探讨了线程并发可能导致的问题,如重复售出相同票号及出现负数票的情况,并分析了这些问题产生的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


package cn.itcast_08;

public class SellTicket implements Runnable {
	// 定义100张票
	private int tickets = 100;

	@Override
	public void run() {
		while (true) {
			// t1,t2,t3三个线程
			// 这一次的tickets = 100;
			if (tickets > 0) {
				// 为了模拟更真实的场景,我们稍作休息
				try {
					Thread.sleep(100); // t1就稍作休息,t2就稍作休息
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
				// 理想状态:
				// 窗口1正在出售第100张票
				// 窗口2正在出售第99张票
				// 但是呢?
				// CPU的每一次执行必须是一个原子性(最简单基本的)的操作。
				// 先记录以前的值
				// 接着把ticket--
				// 然后输出以前的值(t2来了)
				// ticket的值就变成了99
				// 窗口1正在出售第100张票
				// 窗口2正在出售第100张票

			}
		}
	}
	
	@Override
	public void run() {
		while (true) {
			// t1,t2,t3三个线程
			// 这一次的tickets = 1;
			if (tickets > 0) {
				// 为了模拟更真实的场景,我们稍作休息
				try {
					Thread.sleep(100); //t1进来了并休息,t2进来了并休息,t3进来了并休息,
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
				//窗口1正在出售第1张票,tickets=0
				//窗口2正在出售第0张票,tickets=-1
				//窗口3正在出售第-1张票,tickets=-2
			}
		}
	}
}


package cn.itcast_08;

/*
 * 实现Runnable接口的方式实现
 * 
 * 通过加入延迟后,就产生了两个问题:
 * A:相同的票卖了多次
 * 		CPU的一次操作必须是原子性的
 * B:出现了负数票
 * 		随机性和延迟导致的
 */
public class SellTicketDemo {
	public static void main(String[] args) {
		// 创建资源对象
		SellTicket st = new SellTicket();

		// 创建三个线程对象
		Thread t1 = new Thread(st, "窗口1");
		Thread t2 = new Thread(st, "窗口2");
		Thread t3 = new Thread(st, "窗口3");

		// 启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值