这个程序是怎么回事?为什么递减的情况下,小数会跑到大数上面去?
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 星