关于Java多线程的问题

zmscs 2013-11-09 08:40:27
多个线程执行相同的代码,共享票数这个变量,但是我对其中的打印语句有些疑问,先上代码吧:

public class test {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnable mt = new MyRunnable();
Thread mt1= new Thread(mt, "一号窗口");
Thread mt2= new Thread(mt, "二号窗口");
Thread mt3= new Thread(mt, "三号窗口");
mt1.start();
mt2.start();
mt3.start();
}

}

class MyRunnable implements Runnable{

private int ticket = 10;

public void run(){
for(int i =0;i<500;i++){
if(this.ticket>0){
System.out.println(Thread.currentThread().getName() +"卖票---->"+(this.ticket--));
}
}
}
}


输出结果:

一号窗口卖票---->10
一号窗口卖票---->8
一号窗口卖票---->7
一号窗口卖票---->6
一号窗口卖票---->5
一号窗口卖票---->4
一号窗口卖票---->3
一号窗口卖票---->2
一号窗口卖票---->1
二号窗口卖票---->9


从结果上看,第9张票是二号窗口卖出去的,这时候二号窗口的线程应该获得了时间片,但却没有立即打印输出,却在最后打印出来,这是问什么呢?知道的朋友帮帮忙吧,先谢了。
...全文
147 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Asura_X_Y_Y 2013-11-10
  • 打赏
  • 举报
回复
这个跟加锁没关系的。加锁,只是保证输出10到1,而不能保证输出的顺序
CoolEgos 2013-11-09
  • 打赏
  • 举报
回复
嗯嗯,确实是楼上的方法加锁,让只有一个进程在临界区中
CoolEgos 2013-11-09
  • 打赏
  • 举报
回复
学习下,正好在学习进程
zmscs 2013-11-09
  • 打赏
  • 举报
回复
引用 6 楼 Asura_X_Y_Y 的回复:
当刚好二号窗口卖出票后,还没来得急输出,cpu就切到一号窗口了;等一号窗口跑完,切到二号窗口,输出信息。这种cpu的切换,是随机的。
嗯,所以就要加个锁才好
风吹得好舒服 2013-11-09
  • 打赏
  • 举报
回复
5楼的解释是对的,控制台的输出和线程转换之间也是有时间片切换的。而输出是随机的。
Asura_X_Y_Y 2013-11-09
  • 打赏
  • 举报
回复
当刚好二号窗口卖出票后,还没来得急输出,cpu就切到一号窗口了;等一号窗口跑完,切到二号窗口,输出信息。这种cpu的切换,是随机的。
Asura_X_Y_Y 2013-11-09
  • 打赏
  • 举报
回复
这跟控制台输出有关系。“控制台输出”,跟“你运行的程序”,之间也有cpu的切换的
zmscs 2013-11-09
  • 打赏
  • 举报
回复
引用 3 楼 jikemike 的回复:
多个线程都在抢占ticket资源,如果要实现你想法,需要加锁,如下 class MyRunnable implements Runnable{ private int ticket = 10; public void run(){ for(int i =0;i<500;i++){ if(this.ticket>0){ synchronized (this) { System.out.println(Thread.currentThread().getName() +"卖票---->"+(this.ticket--)); } } } } } 一号窗口卖票---->10 三号窗口卖票---->9 三号窗口卖票---->8 一号窗口卖票---->7 一号窗口卖票---->6 一号窗口卖票---->5 一号窗口卖票---->4 一号窗口卖票---->3 一号窗口卖票---->2 一号窗口卖票---->1 二号窗口卖票---->0 三号窗口卖票---->-1
看来对于共享数据的访问,我还不是很了解。多线程方面的书得多看看了。非常感谢。
jikemike 2013-11-09
  • 打赏
  • 举报
回复
多个线程都在抢占ticket资源,如果要实现你想法,需要加锁,如下 class MyRunnable implements Runnable{ private int ticket = 10; public void run(){ for(int i =0;i<500;i++){ if(this.ticket>0){ synchronized (this) { System.out.println(Thread.currentThread().getName() +"卖票---->"+(this.ticket--)); } } } } } 一号窗口卖票---->10 三号窗口卖票---->9 三号窗口卖票---->8 一号窗口卖票---->7 一号窗口卖票---->6 一号窗口卖票---->5 一号窗口卖票---->4 一号窗口卖票---->3 一号窗口卖票---->2 一号窗口卖票---->1 二号窗口卖票---->0 三号窗口卖票---->-1
zmscs 2013-11-09
  • 打赏
  • 举报
回复
引用 1 楼 u010006337 的回复:
友情帮顶

62,614

社区成员

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

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