Semaphore是JDK1.5之后出的一个实现同步的另一个方式。Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程数。假如你有3个资源,有10个线程要使用该资源,同时只能有3个线程使用,所以其余7线程在等待,只要3个中任意一个释放资源,那么7个线程中的一个就可以使用了。
另外,7个线程等待可以使随机获取机会,也可以是按照先来后到的顺序获得机会,这取决与Semaphore的构造时传入的参数。
单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是有一个线程获得了锁,再有另一个线程去释放改锁,可以实现死锁恢复。
构造方法摘要 | |
---|---|
Semaphore(int permits) 创建具有给定的许可数和非公平的公平设置的 Semaphore 。 | |
Semaphore(int permits, boolean fair) 创建具有给定的许可数和给定的公平设置的 |
具体实现如下:
package andy.thread.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author Zhang,Tianyou
* @version 2014年11月9日 下午1:49:25
*/
public class ThreadSemaphoreTest {
public static void main(String[] args) {
// 定义一个缓存线程池
ExecutorService threadPool = Executors.newCachedThreadPool();
final int MAX_AVAILABLE = 100;
// 定义信号量 等待线程使用公平原则 先来后到
Semaphore semaphore = new Semaphore(MAX_AVAILABLE, true);
for (int i = 0; i < 10; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
// 此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// availablePermits() 返回此信号量中当前可用的许可数。
System.out
.println("线程"
+ Thread.currentThread().getName()
+ "进入,当前已有"
+ (MAX_AVAILABLE
- semaphore.availablePermits() + "个并发"));
try {
Thread.sleep((long) (Math.random() * 10000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName()
+ "即将离开");
// 释放一个许可,将其返回等待线程给信号量。
semaphore.release();
}
};
threadPool.execute(runnable);
}
}
}
运行效果如下:
线程pool-1-thread-1进入,当前已有1个并发
线程pool-1-thread-3进入,当前已有2个并发
线程pool-1-thread-2进入,当前已有3个并发
线程pool-1-thread-5进入,当前已有4个并发
线程pool-1-thread-7进入,当前已有5个并发
线程pool-1-thread-4进入,当前已有6个并发
线程pool-1-thread-6进入,当前已有7个并发
线程pool-1-thread-8进入,当前已有8个并发
线程pool-1-thread-9进入,当前已有9个并发
线程pool-1-thread-10进入,当前已有10个并发
线程pool-1-thread-5即将离开
线程pool-1-thread-3即将离开
线程pool-1-thread-6即将离开
线程pool-1-thread-7即将离开
线程pool-1-thread-2即将离开
线程pool-1-thread-8即将离开
线程pool-1-thread-9即将离开
线程pool-1-thread-10即将离开
线程pool-1-thread-1即将离开
线程pool-1-thread-4即将离开