这个程序是怎么回事?为什么递减的情况下,小数会跑到大数上面去?
public class SellTicket extends Thread { // 定义100张票 // private int tickets = 100; // 为了让多个线程对象共享这100张票,我们其实应该用静态修饰 private static int tickets = 100; @Override public void run() { // 定义100张票 // 每个线程进来都会走这里,这样的话,每个线程对象相当于买的是自己的那100张票,这不合理,所以应该定义到外面 // int tickets = 100; // 是为了模拟一直有票 while (true) { if (tickets > 0) { System.out.println(getName() + "正在出售第" + (tickets--) + "张票"); } } } }
/* * 某电影院目前正在上映贺岁大片(红高粱,少林寺传奇藏经阁),共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。 * 继承Thread类来实现。 */ public class SellTicketDemo { public static void main(String[] args) { // 创建三个线程对象 SellTicket st1 = new SellTicket(); SellTicket st2 = new SellTicket(); SellTicket st3 = new SellTicket(); // 给线程对象起名字 st1.setName("窗口1"); st2.setName("窗口2"); st3.setName("窗口3"); // 启动线程 st1.start(); st2.start(); st3.start(); } }
正在回答
同学你好,这是计算机底层的执行原理。对虚拟机来说,多线程时,指令有时候会乱序执行。这是底层执行原理的问题,同学暂时记住即可。
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
同学你好,原因如下:
System.out.println(getName() + "正在出售第" + (tickets--) + "张票");
将以上命令分为三步:
tickets=tickets; 输出语句; tickets=tickets-1:
输出语句对于虚拟机来说是很多条指令,多线程时,指令乱序执行。
例如,tickets初始值为100。
1、线程A在执行tickets=tickets;后,将tickets=100存入寄存器,不执行输出语句,继续向下执行tickets=tickets-1;,将tickets=99存入内存。
2、这时,线程B获取执行权,从内存读取tickets=99,向下执行,输出语句“正在出售第99张票",执行tickets=tickets-1;,tickets=98。
3、线程A重新获取执行权,从寄存器读取tickets=100,输出“正在出售第100张票”。
解决方法:
将这段代码包在同步代码块里,即加锁执行,如下图所示:
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
同学你好
1、SellTicket实现Runnable接口
2、在循环中,需要为该对象加锁。
3、当票数<0时,退出循环,程序不再执行。
原因如下:
CPU可能随机的在多个处于就绪状态中的线程中进行切换,这时就可能出现线程的安全问题;
解决安全问题则需要同步锁的加入,执行synchronized部分代码的时候必须需要对象锁,
而一个对象只有一个锁,只有执行完synchronized里面的代码后释放锁,其他线程才可以获得锁。
那么就保证了同一时刻只有一个线程访问synchronized里面的代码。实现资源共享的关键是:只有一个实例,synchronized使用的是同一把锁,用实例的锁或者定义一个实例。
这就需要使用实现Runnable接口的方式,实现多线程,这样传入的是一个实例。
继承Thread的方式,传入的是多个实例,每个实例都有一个锁,那就无法实现控制。
修改代码如下图所示:
4、创建一个SellTicket对象
5、创建三个线程,将SellTicket对象传入
修改代码如下图所示:
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
- 参与学习 人
- 提交作业 3802 份
- 解答问题 11489 个
本阶段带你迈入Java世界,学习Java必备基础知识,基础语法、面向对象思想以及常用工具类的使用。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星