Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
public class SemaphoreDemo {
public static void main(String[] args)
{
Runnable limitedCall = new Runnable() {
final Random rand = new Random();
//一共只有三个坑,没有释放的就等待
final Semaphore available = new Semaphore(3);
public void run()
{
int time = rand.nextInt(15);
try
{
available.acquire();
System.out.println("Executing " +
"long-running action for " +
time + " seconds... #" + Thread.currentThread().getName());
Thread.sleep(time * 1000);
System.out.println("Done with #" +
Thread.currentThread().getName() + "!");
available.release();
}
catch (InterruptedException intEx)
{
intEx.printStackTrace();
}
}
};
for (int i=0; i<10; i++)
new Thread(limitedCall).start();
}
}
执行结果如下:
Executing long-running action for 7 seconds... #Thread-1
Executing long-running action for 2 seconds... #Thread-2
Executing long-running action for 14 seconds... #Thread-0
Done with #Thread-2!
Executing long-running action for 1 seconds... #Thread-3
Done with #Thread-3!
Executing long-running action for 4 seconds... #Thread-7
Done with #Thread-1!
Executing long-running action for 10 seconds... #Thread-9
Done with #Thread-7!
Executing long-running action for 1 seconds... #Thread-6
Done with #Thread-6!
Executing long-running action for 9 seconds... #Thread-5
Done with #Thread-0!
Executing long-running action for 6 seconds... #Thread-4
Done with #Thread-9!
Executing long-running action for 12 seconds... #Thread-8
Done with #Thread-5!
Done with #Thread-4!
Done with #Thread-8!
可以从结果当中看出,线程1,2,0三个线程限制性。后续线程需要执行必须等到释放掉该信号量。
补充:
计数信号的一种特殊情况是互斥,或者互斥信号。互斥就是具有单一许可权的计数信号,意味着在给定时间仅一个线程可以具有许可权(也称为二进制信号)。互斥可以用于管理对共享资源的独占访问。
虽然互斥许多地方与锁定一样,但互斥还有一个锁定通常没有的其他功能,就是互斥可以由具有许可权的线程之外的其他线程来释放。这在死锁恢复时会非常有用。