java多线程重复卖票的问题
来源:互联网 发布:查询某一列重复的数据 编辑:程序博客网 时间:2024/05/21 22:55
上代码:
public class Test {public static void main(String[] args) { ThreadTicket ticket = new ThreadTicket(); Thread t1 = new Thread(ticket); Thread t2 = new Thread(ticket); t1.start(); t2.start(); }}class ThreadTicket implements Runnable { int ticket = 10; @Override public void run() {while(true) {if(ticket>0) {try {Thread.currentThread();Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"卖。。。"+ticket--); } else {break;}} }}运行结果:
Thread-1卖。。。10Thread-0卖。。。10Thread-0卖。。。9Thread-1卖。。。8Thread-1卖。。。7Thread-0卖。。。6Thread-0卖。。。4Thread-1卖。。。5Thread-0卖。。。3Thread-1卖。。。2Thread-1卖。。。1Thread-0卖。。。0
问题:偶尔会出现重复卖票的情况,显示这在开发中是不允许的
原因分析:java中的原子性操作,是指读和写是原子性的,比如 i=5,这就是一个原子性的操作。多线程执行的时候,只能在一个原子操作力,才会没有并发读或并发写的情况。
通常情况下,在java里面,i++或者i--不是线程安全的,这里面有三个独立的操作:获得变量当前的值,为该值+1或者-1,然后写回新的值。
在没有额外资源可以利用的情况下,只能使用加锁才能保证读-改-写这三个操作是原子性的,这就是为什么会出现一定数量重复卖票的情况
另外,sleep()中指定的时间是线程不会运行的最短时间,因此,sleep()方法不能保证该线程睡眠到期后就开始执行,所以,加上sleep()以后,就增加了并发操作ticket()的机会,出现重复卖票的可能性也会增加
修改后代码:
class ThreadTicket implements Runnable { int ticket = 10; @Override public void run() {synchronized (this) {while(true) {if(ticket>0) {try {Thread.currentThread();Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"卖。。。"+ticket--); } else {break;}}} }}运行结果:
Thread-0卖。。。10Thread-0卖。。。9Thread-0卖。。。8Thread-0卖。。。7Thread-0卖。。。6Thread-0卖。。。5Thread-0卖。。。4Thread-0卖。。。3Thread-0卖。。。2Thread-0卖。。。1
1 0
- java多线程重复卖票的问题
- java多线程卖票问题。
- Java 多线程卖票演示
- Java多线程-卖票
- Java 多线程卖票
- Java 多线程卖票例子
- JAVA多线程实现模拟卖票
- java多线程:6、模拟卖票
- Java多线程实例之卖票
- 多线程实现卖票的例子
- java 线程同步--卖票问题
- Java 线程同步 卖票问题
- java卖票线程问题synchronized
- 多线程卖票
- 多线程经典问题之多窗口卖票
- 【java】多线程小例子(卖票示例)
- Java多线程—两种卖票
- java简单的卖票程序
- XPHSF
- IOS-简单易懂的Block回调使用
- Windows驱动开发如何入门
- 算法概论 - 8.19
- 【spring】ssm整合小知识
- java多线程重复卖票的问题
- 50道Java线程面试题
- ThinkPHP学习笔记(二):ThinkPHP框架的模板技术
- 开源软件2017年的四大挑战
- 头像截取上传并预览
- ArcGIS Server 10.2安装
- Python 异常处理--raise函数用法
- Eclipse上安装CDT插件
- POJ-1611 The Suspects (并查集模板题)