- 簡(jiǎn)單的Semaphore實(shí)現(xiàn)
public class Semaphore {
private boolean signal = false;
public synchronized void take() {
this.signal = true;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(!this.signal) wait();
this.signal = false;
}
}
- 使用Semaphore來(lái)發(fā)出信號(hào)
Semaphore semaphore = new Semaphore();
SendingThread sender = new SendingThread(semaphore)怎棱;
ReceivingThread receiver = new ReceivingThread(semaphore);
receiver.start();
sender.start();
public class SendingThread {
Semaphore semaphore = null;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
//do something, then signal
this.semaphore.take();
}
}
}
public class RecevingThread {
Semaphore semaphore = null;
public ReceivingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
this.semaphore.release();
//receive signal, then do something...
}
}
}
- 可計(jì)數(shù)的Semaphore
public class CountingSemaphore {
private int signals = 0;
public synchronized void take() {
this.signals++;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.signals--;
}
}
- 有上限的Semaphore
public class BoundedSemaphore {
private int signals = 0;
private int bound = 0;
public BoundedSemaphore(int upperBound){
this.bound = upperBound;
}
public synchronized void take() throws InterruptedException{
while(this.signals == bound) wait();
this.signals++;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.signals--;
this.notify();
}
}
- 把Semaphore當(dāng)鎖來(lái)使用
BoundedSemaphore semaphore = new BoundedSemaphore(1);
...
semaphore.take();
try{
//critical section
} finally {
semaphore.release();
}
例子:
public class SemaphoreTest {
public static void main(String[] args) {
ExecutorService service= Executors.newCachedThreadPool();
final Semaphore sp=new Semaphore(3);
for (int i=0;i<10;i++){
Runnable runnable=new Runnable() {
@Override
public void run() {
try {
sp.acquire();
}catch (Exception e){
e.printStackTrace();
}
System.out.println("線(xiàn)程"+Thread.currentThread().getName()+"進(jìn)入,當(dāng)前已有"+(3-sp.availablePermits()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println("線(xiàn)程"+Thread.currentThread().getName()+"離開(kāi)墩新,當(dāng)前已有"+(3-sp.availablePermits()));
sp.release();
System.out.println("線(xiàn)程"+Thread.currentThread().getName()+"離開(kāi),當(dāng)前已有"+(3-sp.availablePermits()));
}
};
service.execute(runnable);
}
}
}
輸出結(jié)果:
線(xiàn)程pool-1-thread-1進(jìn)入羔味,當(dāng)前已有1
線(xiàn)程pool-1-thread-2進(jìn)入卡辰,當(dāng)前已有2
線(xiàn)程pool-1-thread-3進(jìn)入,當(dāng)前已有3
線(xiàn)程pool-1-thread-2離開(kāi)拱绑,當(dāng)前已有1
線(xiàn)程pool-1-thread-6進(jìn)入综芥,當(dāng)前已有3
線(xiàn)程pool-1-thread-3離開(kāi),當(dāng)前已有2
線(xiàn)程pool-1-thread-1離開(kāi)猎拨,當(dāng)前已有3
線(xiàn)程pool-1-thread-5進(jìn)入膀藐,當(dāng)前已有3
線(xiàn)程pool-1-thread-4進(jìn)入,當(dāng)前已有2