【发布时间】:2013-12-18 15:45:11
【问题描述】:
我对 java.util.concurrent 包中的“Semaphore”类有点困惑。这是我的代码 sn-p:
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();
}
}
}
我知道它可以用来控制对资源的访问。如果我将限制设置为一个,例如“Semaphore limit = new Semaphore(1);”,它看起来就像一个锁。事实证明。如果我将限制设置为两个,我希望在给定时间内有两个线程可以访问 increment() 方法,这可能会导致数据竞争。输出可能是这样的:
- [sThread3]:增量之前。当前计数器:2
- [sThread4]:增量之前。当前计数器:2
- [sThread3]:获取资源。开始递增。
- [sThread4]:获取资源。开始递增。
- [sThread3]:增量完成。当前计数器:3
- [sThread4]:增量完成。当前计数器:3
但是,虽然我尝试了几次,但都没有出现预期的结果。所以我想知道我是否误解了它。谢谢。
【问题讨论】:
-
您应该将循环放在 run() 方法中 - 启动线程需要时间并减少交错的可能性...
-
它在一个线程中@assylias
-
@RamonBoza 每个线程只运行一条指令
s.increment(),因此启动线程的时间实际上比increment的时间长得多——为了有机会观察交错和竞速,你需要及时拨打increment。例如在每个线程中调用increment10000 次。
标签: java multithreading semaphore