没法实现的同步多线程购票系统,郁闷

无法实现的同步多线程购票系统,郁闷结果有买到同样票的和0的情况……求解,why?public class Shop {public st

无法实现的同步多线程购票系统,郁闷
结果有买到同样票的和0的情况……求解,why?没法实现的同步多线程购票系统,郁闷

public class Shop 
{
public static void main(String[] args) 
{
Outer o=new Outer();
o.getSale("s1:").start();
o.getSale("s2:").start();

}

}

class Outer
{
private  int ticket=20;

public  Thread getSale(String s)
{

return new Sale(s);
}

private class Sale extends Thread
{
 Sale(String s) 
{
super(s);
}


public synchronized void run()
{
//int tmp=ticket;
while(ticket>0)
{
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+" ticket "+ticket--);
//ticket=tmp;
}
}
}
}

[解决办法]
package cn.dzr.thread;

public class SocketTest
{
    public static void main(String[] args) 
    {
        Outer o=new Outer();
        o.getSale("s1:").start();
        o.getSale("s2:").start();
         
    }
     
}
 
class Outer
{
     
     
    public  Thread getSale(String s)
    {
         
        return new Sale(s);
    }
     
    private class Sale extends Thread
    {
         Sale(String s) 


        {
            super(s);
        }
          
          
         
         synchronized(this)  //这个是在类里定义的,怎么可能通过,你需要在一个方法里定义他。run里。
         {//不过你用this,貌似依旧不能解决问题。
         //最好Outer类中定义一个object对象,然后用他做
         //同步锁,这样就保证了两个锁的一致..
             private  int ticket=20;
                public  void run()
                {
                     
                    //int tmp=ticket;
                    while(ticket>0)
                    {
                        try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(getName()+" ticket "+ticket--);
                        //ticket=tmp;


                    }
                }
         }
     
    }
}


[解决办法]
public void run()
{

while (ticket > 0)
{
synchronized (o)
{
System.out.println(getName() + " ticket " + ticket--);
try
{
sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}

}
}

}

改成这样就行啦。不过sleep要在System.out.println(....)的下面。
如果在前面的话,线程1进去之后,先休息1秒。
如果当时刚好是ticket = 1.
这个时候,run方法被线程2执行,他进去之后,发现ticket = 1; 于是可以往下执行去。

线程1再次从sleep初唤醒。
就会输出0。。