Java 关于信号量类有点困惑

Java 关于信号量类有点困惑,java,multithreading,semaphore,Java,Multithreading,Semaphore,我对java.util.concurrent包中的“信号量”类有些困惑。以下是我的代码片段: import java.util.concurrent.Semaphore; public class TestSemaphore { public static void main(String[] args){ Semaphore limit = new Semaphore(2); SemaphoreAA s = new SemaphoreAA(limit)

我对java.util.concurrent包中的“信号量”类有些困惑。以下是我的代码片段:

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();
        }
    }
}
import java.util.concurrent.Semaphore;
公共类测试信号量{
公共静态void main(字符串[]args){
信号量限制=新信号量(2);
信号量A s=新信号量A(限制);
AAThread a=新的AAThread;
线程[]sThread=新线程[100];

对于(inti=0;i您理解得对。

然而,尽管我试了好几次,结果却没有达到预期的效果

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


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

您应该将循环置于运行状态()方法-启动一个线程需要时间,并减少交错的可能性…它在一个线程中@assylias@RamonBoza每个线程只运行一条指令
s.increment()
因此,启动线程的时间实际上比
increment
要长得多-为了有机会观察交织和竞速,您需要在更近的时间内调用
increment
。例如,在每个线程中调用
increment
10000次。我找到了您,这就是为什么我尝试了好几次并将线程数增加到100(而不是10)以捕获预期结果。但是,这不起作用。@franksunn尝试在递增之前将该值赋给局部变量,然后执行
if(local+1!=counter){fail();}
在这种情况下,您可以反复运行它,直到最终失败。还可以删除
System.out.println
,因为它添加了可能影响结果的其他同步点