2013-07-27 18 views
1

我试图实现一个简单的问题,我有一个全局变量出售门票。 我生成3个线程销售10张票,这是我使用二进制信号量。二进制信号灯的使用 - 无法正常工作(销售门票)

private static int noOfTickets =10; 
private static boolean soldAll = false; 
private static Random r = new Random(10); 

/************ MAIN **************/ 
public static void main(String[] arg){ 
    // spawn 10 threads to see a tickets 

    for(int i =0; i<3; i++){ 
     Thread t = new Thread(new sellRunnable()); 
     t.setName("Me_"+i); 
     t.start(); 
    } 
} 
/************ MAIN **************/ 


public static void sell() throws InterruptedException{ 
    Semaphore b = new Semaphore(1); 
    int numOfTicketsSoldByThisThread = 0; 
    while(!soldAll){ 

     addRandomDelay(1000, 100); 

     b.acquire(); 
     if(noOfTickets>0){ 
      Thread t = Thread.currentThread(); 
      numOfTicketsSoldByThisThread++; 
      noOfTickets--; 
      System.out.println("I "+t.getName()+" sold "+numOfTicketsSoldByThisThread+"ticket. tickets left are "+noOfTickets); 


     }else{ 
      soldAll = true; 
      System.out.println(" sold all tickets"); 
     } 
     b.release(); 
    }// end of while 


} 

public static class sellRunnable implements Runnable{ 

    public void run() { 
     try { 
      sell(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 

} 

当我运行这段代码,我没有得到正确的输出,在时间 某些时候,我得到这个

  • 我ME_2卖1ticket。门票剩余7
  • 我Me_1卖1ticket。左边的门票是7

请注意,两个线程是如何打印出票剩下的是7 ?.这不可能是正确的?我知道noOfTicketsLeft--不是一个原子操作,但它在信号量内。所以,它应该工作?

回答

1

您需要为所有三个线程使用相同的Semaphore实例。就目前而言,它们都指向不同的信号量,所以它们实际上并没有互相锁定。

顺便说一句,即使这看起来可能只是为了快速练习,你真的应该摆脱使用静态变量的习惯;声明一个类,然后实例化它并在main()中调用它。它不需要更多的努力,而且它更干净。

+0

我同意。我只是删除了所有的静态变量。感谢您注意到我的错误!它现在有效。 – 12rad