public class TicketsSystem
{
public static void main(String args[])
{
SellTickets st=new SellTickets();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
}
}
class SellTickets implements Runnable
{
int tickets=100;
public void run()
{
while(tickets>0)
{
if(tickets==1)
{
try{
Thread.sleep(10);
}catch(Exception e)
{
e.printStackTrace();
}
}
System.out.println(tickets);
tickets--; }
}
}
最后四行输出结果是:
4
3
2
-2
我不明白的地方是:1,0,-1这三个数为什么没有输出呢?

解决方案 »

  1.   

    因为tickets--不是原子性操作,所以就会发生线程不同步问题,在定义tickets前加上volatile就行了,让tickets--变成原子性操作,或在run方法里加个同步块吧,两种都可以,代码如下:
    public class TicketsSystem {
    public static void main(String args[]) {
    SellTickets st = new SellTickets();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    }
    }class SellTickets implements Runnable {
    volatile int tickets = 100; public void run() {
    while (tickets > 0) {
    if (tickets == 1) {
    try {
    Thread.sleep(10);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    System.out.println(tickets);
    tickets--; }
    }
    }
      

  2.   

    chenyuelin311() 
     我还是不懂原子性操作是意思?
    同时你修改后的原代码我调试了下,结果跟我的还是一样.我想问的是:按照我的程序,为何没有输出1,0,-1这三个数呢?希望有一个真正的高手,把这个程序的执行过程讲一下,分不够的话,可以再加!
      

  3.   

    你这个程序的结果应该来说是随机的,并不是你指得不出现3,2,1. 在任何售票系统中,假如A售票点在查询(仅仅是查询票x,不一定会卖出)你就必须对票x进行一次锁定,B售票点是不可以查到x这张票的。 否则出现a,b同时卖掉票x的情况。你的程序大概就是这个问题,要锁定对售票的-1操作!
      

  4.   

    改一个地方就行了,public synchronized void run()  ,把对票的操作函数加同步。当然这个效率不算高,方便理解而已。最好只锁定ticket-1 操作
      

  5.   

    首先要明白线程的cpu分配时间是由操作系统决定的
    比如有三个线程(线程一,线程二,线程三)在走到System.out.println(tickets);之后,tickets--之前,它们的cpu分配时间刚好完了,此时tickets==4,换第四个线程,它打印出4,3,2以后,tickets==1,此时第四个线程进入sleep,然后第一个线程的cpu分配时间到了,执行tickets--,这时tickets==0,当它再次走到System.out.println(tickets);之前,它的cpu分配时间又完了,这时换第二个线程,它执行tickets--,此时tickets==-1,当它又再次执行到System.out.println(tickets);之前,此时它的cpu分配时间又完了,换第三个,它执行tickets--,此时tickets==-2,于是,继续执行,就有了LZ所看到的结果了。
      

  6.   

    volatile的本意是一个线程修改成员变量时,共享内存立即发生相应的改变,另外的线程也能同时获得修改后的新值,这里应该和这个没太大关系
      

  7.   

    volatile的本意是一个线程修改成员变量时,共享内存立即发生相应的改变,另外的线程也能同时获得修改后的新值,这里应该和这个没太大关系
    啊宝说的很好的啊
    volatile本来就是线程修改成员变量时 共享内存发生改变够 其他线程也同时得到修改后的值
      

  8.   

    这个系统真是简单啊.呵呵.
    实时系统的解决方法是:
    java:声明方法为synchronized
    C++:调用EnterCritcalSection
      

  9.   

    public   class   aa 

    public   static   void   main(String   args[]) 

    SellTickets   st=new   SellTickets(); 
    new   Thread(st).start(); 
    new   Thread(st).start(); 
    new   Thread(st).start(); 
    new   Thread(st).start(); 


    class   SellTickets   implements   Runnable 

    int   tickets=100; 
    public   void   run() 

    while(true) 

    synchronized(this)
    {
    if(tickets>0) 

    try{ 
    Thread.sleep(10); 
    }catch(Exception   e) 

    e.printStackTrace(); 

    System.out.println(tickets); 
    tickets--; 


    }

    }