对Semaphore Class有点困惑

时间:2013-12-18 15:45:11

标签: java multithreading semaphore

我对java.util.concurrent包中的“Semaphore”类感到困惑。这是我的代码片段:

import java.util.concurrent.Semaphore;

public class TestSemaphore {
    public static void main(String[] args){
        Semaphore limit = new Semaphore(2);
        SemaphoreAA s = new SemaphoreAA(limit);
        AAThread a = new AAThread(s);
        Thread[] sThread = new Thread[100];
        for(int i = 0; i<100; i++){
            sThread[i] = new Thread(a,"[sThread"+i+"]");
            sThread[i].start();

        }
    }
}

class SemaphoreAA{
    private static int counter;
    private Semaphore limit;

    public SemaphoreAA(Semaphore limit){
        this.limit = limit;
    }

    public void increment() throws InterruptedException{
        System.out.printf("%-15s%-25s%5d%n",Thread.currentThread().getName()," : Before Increment. Current counter: ",counter);
        limit.acquire();
        System.out.printf("%-15s%-25s%n",Thread.currentThread().getName()," : Get the resource. Start to increment.");
        counter++;
        System.out.printf("%-20s%-40s%5d%n",Thread.currentThread().getName()," : Increment is done. Current counter: ",counter );
        limit.release();
    }
}

class AAThread implements Runnable{
    private SemaphoreAA s;

    public AAThread(SemaphoreAA s){
        this.s = s;

    }

    public void run() {
        try {
            s.increment();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

我知道它可以用来控制对资源的访问。如果我将限制设置为1,就像这个“Semaphore limit = new Semaphore(1);”,它似乎是一个锁。事实证明。如果我将限制设置为2,我希望在给定时间内有两个线程可以访问increment()方法,这可能会导致数据争用。输出可能是这样的:

  
      
  • [sThread3]:增量之前。目前的柜台:2
  •   
  • [sThread4]:增量之前。目前的柜台:2
  •   
  • [sThread3]:获取资源。开始增加。
  •   
  • [sThread4]:获取资源。开始增加。
  •   
  • [sThread3]:增量完成。当前柜台:3
  •   
  • [sThread4]:增量完成。当前柜台:3
  •   

然而,虽然我曾多次尝试,但预期的结果并未发生。所以我想知道我是否误解了它。感谢。

1 个答案:

答案 0 :(得分:3)

你明白了。

  

然而,虽然我曾多次尝试,但预期的结果并未发生。

仅仅因为它可以出现并不意味着它会。这是大多数并发错误的问题:它们有时会出现,有时不出现。

如果您想增加出错的可能性,可以增加Thread的数量,或者在两个不同的循环中创建/启动它们。