我这个java的多线程为什么会出现两个十票?而且不是一直出现,是程序运行个7到8次才出现一次两个十票。

Knight-2020 2016-12-28 10:53:54

public class Test00 {
public static void main(String[] args) {
TicketRunnable tr=new TicketRunnable();
new Thread(tr,"线程1").start();
new Thread(tr,"线程2").start();
}
}

class TicketRunnable implements Runnable {
private int i=10;
public void run(){
while(i>=1){
System.out.println(Thread.currentThread().getName()+"卖第"+i--+"张票");
}

}
}



为什么结果有两种:
第一种:
线程1卖第10张票
线程2卖第9张票
线程2卖第7张票
线程2卖第6张票
线程1卖第8张票
线程1卖第4张票
线程2卖第5张票
线程2卖第2张票
线程1卖第3张票
线程2卖第1张票

第二种:
线程1卖第10张票
线程1卖第9张票
线程1卖第8张票
线程2卖第10张票
线程2卖第6张票
线程1卖第7张票
线程1卖第4张票
线程2卖第5张票
线程2卖第2张票
线程2卖第1张票
线程1卖第3张票

而且第二种的结果一般是程序运行7到8次才会出现。原理是什么?这涉及到cpu的工作原理?

...全文
691 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzd_10010 2017-12-06
  • 打赏
  • 举报
回复
创建同步锁,这样两个线程只有一个能持有当前10张票的售卖权,不然就会出现你这种卖重复的情况
Mrlw 2017-12-05
  • 打赏
  • 举报
回复
典型的线程不安全例子=.= 楼上已经有好多解决方案了
wzd_10010 2017-12-05
  • 打赏
  • 举报
回复
线程的执行顺序与优先级有一定的关系,但也就是概率问题不是一定的,这个看谁得到时间碎片了
大脸丶程序猿 2017-11-23
  • 打赏
  • 举报
回复
使用同步锁,会解决你的问题
逗比123号 2017-11-23
  • 打赏
  • 举报
回复
又是线程入门问题
byte[0] 2017-11-23
  • 打赏
  • 举报
回复
线程是cpu分配的,你没有加锁,这里就会有一个资源竞争问题。
ascarl2010 2017-11-23
  • 打赏
  • 举报
回复
发现运行结果每一次都不同。 因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。 明确一点,在某一个时刻,只能有一个程序在运行。(多核除外) cpu在做着快速的切换,以达到看上去是同时运行的效果。 我们可以形象把多线程的运行行为在互相抢夺cpu的执行权。 多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。
Clumsy__Cat 2017-11-23
  • 打赏
  • 举报
回复
由于没有加锁,线程的运行你可以认为是无序的,既你无法确定当前是哪个线程在运行。这跟你的cpu有关系,是cpu控制的线程的运行
ascarl2010 2017-11-23
  • 打赏
  • 举报
回复
你如果有1000张票,估计每次运行程序都会产生不同的结果,那是因为CPU会随机挑选线程去执行,不同线程都争着想要被CPU挑选上,所以可以利用同步锁,让他们排队,使线程有序的去被执行
土豆大土豆 2017-10-26
  • 打赏
  • 举报
回复
线程安全问题,加个锁就好了
isOkFine 2017-10-25
  • 打赏
  • 举报
回复
加个锁就好了的 while (i > 1) { synchronized (this) { System.out.println(Thread.currentThread().getName() + "卖第"+ i-- + "张票");} }
bree06 2016-12-28
  • 打赏
  • 举报
回复
i--; 不是一个原子操作且i是共享的. 所以你的代码不是线程安全的. 但是由于循环10次的操作用时极短, 线程启动也是需要时间的, 所以出现不重复数据次数较少. 想要保证正常出票可以将 int i=10;改为AtomicInteger i = 10; 或者将int i=10;前面加上volatile关键字.
X元素 2016-12-28
  • 打赏
  • 举报
回复
线程是有锁的概念的,建议楼主先看一下。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧