结果有买到同样票的和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;
}
}
}
}

解决方案 »

  1.   

    锁对象不同 和ticket不是共享数据
      

  2.   

    public class Shop 
    {
    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)
     {
     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;
    }
    }
     }

    }
    }改动后编译都不通过了
      

  3.   

    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;
                        }
                    }
             }
         
        }
    }
      

  4.   

    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。。
      

  5.   

    sleep在System.out.println(....)的下面   依然会出现输出0的情况啊 
      

  6.   

    在print语句前面再加个if判断票是否大于0就行了
      

  7.   


    由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁。所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象
      

  8.   

    ticket必须放在线程类或是void方法中?这个是外部类的数据,子类访问的是同一个外部类对象的呀,不是相当于共享么?
      

  9.   

    ticket必须放在线程类或是void方法中?这个是外部类的数据,子类访问的是同一个外部类对象的呀,不是相当于共享么?
    this是代表对象,你创建一个新的对象,this自然不同了。除非是访问同一个对象创的方法。否则this是没有效果的。