public class ticketTread implements Runnable{ static boolean flag=true;
int count=200;
public void run()
{


while(flag&&count>=0)
{
synchronized(this)
{

System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
    count--;

}
    try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}
public static void safeStop()
{

flag=false;

}


}import java.io.IOException;
public class ticketDemo { /**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
             ticketTread tr=new ticketTread();
             Thread t1=new Thread(tr);
             Thread t2=new Thread(tr);
             Thread t3=new Thread(tr);
             Thread t4=new Thread(tr);
             t1.start();
             t2.start();
             t3.start();
             t4.start();
             //阻塞
             try {
System.in.read();
ticketTread.safeStop();  
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
            
}}
// 结果打印出了

解决方案 »

  1.   

    double check就可以了
    public void run() { while (flag && count >= 0) {
    synchronized (this) {
    if(count >= 0){
    System.out.println("这是" + Thread.currentThread().getName()
    + "在卖" + count + "张票");
    count--;
    }
    }
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } }
      

  2.   

    将while循环放进同步块内, 但是要将sleep() 改成wait()方法,因为sleep不会释放锁,wait方法会释放锁。避免线程不能交替运行。 并且将wait方法放进while循环内。
    修改run方法为:public void run()
    {
    synchronized(this)
    {
    while(flag&&count>=0)
    {

    System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
    count--;
    try {
    this.wait(10);  
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }或者在同步块内再加上判断。public void run()
    {
    while(flag&&count>=0)
    {
    synchronized(this)
    {
    if(flag&&count>=0){ //这里再加上判断
    System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
    count--;
    }else{
    return ;
    } }
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block  
    e.printStackTrace();
    }
    }
    }
      

  3.   


    正解等待的时候,,count很可能已经改变了
      

  4.   

    为什么要加第二个控制if(count>=0)  第一个控制不住么??
      

  5.   

    找本操作系统的书来看看  或者<<java并发编程实战>>  这是很简单的问题
      

  6.   


    the right answer~
      

  7.   

    其实这个问题比较简单,就是判断完count>0之后count还有可能改变,就有可能小于0了。比如此时count=0 第一个线程执行到System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");第二个线程执行到
    while(flag&&count>=0)此时满足条件遇到锁第二个线程等待,继续执行第一个线程count--,此时count为-1,然后第二个线程抢到资源执行输出语句,但此时count为-1了,所以就错了。解决方法就是把while语句也锁进去,或在进行一次判别。
    希望能帮助楼主
      

  8.   

    呵呵,楼主synchronized地方放错了才导致这个打印出负数的问题的,首先说明下楼主的代码中while(flag&&count>=0)
    {
    /*synchronized放在while循环体的内部,假设当前线程是t1,执行到count == 0时 while执行完但还未进入到synchronized块的时候可能会被其他线程抢占此资源 假设是t2,执行run()方法打印出count == 0,然后count-- ,此时count == -1,但此时对于t1来说while语句已经判断了!所以对于t1来说它会直接调用System.out.println()方法,打印的却是count为-1时的语句*/
    synchronized(this)正确的解决办法是将synchronized(this)放在while语句之外,至于为什么,请楼主自己思考。