我對java.util.concurrent包中的「Semaphore」類感到困惑。這裏是我的代碼片段:對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,就像這個「信號量限制=新的信號量(1)」,它看起來像是一個鎖。它被證明。如果將限制設置爲2,我預計在給定時間內有兩個線程可以訪問increment()方法,並且可能會導致數據競爭。輸出可能是這樣的:
- [sThread3]:之前遞增。當前計數器:2
- [sThread4]:增量前。當前計數器:2
- [sThread3]:獲取資源。開始增加。
- [sThread4]:獲取資源。開始增加。
- [sThread3]:增量完成。當前計數器:3
- [sThread4]:遞增完成。當前計數器:3
不過,雖然我已經試了好幾次,並沒有出現預期的結果。所以我想知道我是否誤解了它。謝謝。
你應該把循環放在run()方法中 - 啓動線程需要時間並減少交錯的可能性... – assylias
它在一個線程@assylias – RamonBoza
@RamonBoza每個線程只運行一條指令's.increment ()'所以啓動線程的時間實際上比「增量」的時間要長得多 - 爲了有機會觀察交錯和競速,你需要及時調用「增量」。例如在每個線程中調用「increment」10000次。 – assylias