信号量 Semaphore
Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。
package learnthread.ftask; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; public class BoundHashSet<T> { private final Set<T> set; private final Semaphore sem;// 信号量 public BoundHashSet(int bound) { set = Collections.synchronizedSet(new HashSet<T>()); sem = new Semaphore(bound); } public boolean add(T o) throws InterruptedException { sem.acquire(); boolean wasAdd = false; try { set.add(o);// 添加时可能由于资源耗尽,添加会出异常,需要判断是否真的添加,如果添加则释放 wasAdd = true; } finally { if (!wasAdd) { sem.release(); } } return wasAdd; } public boolean remove(T o) { boolean remove = set.remove(o); if (remove) { sem.release(); } return remove; } public String toString() { return set.toString(); } public static void main(String[] args) { final BoundHashSet<Integer> set = new BoundHashSet<Integer>(3); final CountDownLatch latch = new CountDownLatch(2); Thread t1 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 4; i++) { try { System.out.println("正在添加元素" + i); System.out.println(set.add(i)); } catch (InterruptedException e) { e.printStackTrace(); } } latch.countDown(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("正在移除元素"); System.out.println(set.remove(1)); latch.countDown(); } }); t1.start(); t2.start(); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(set.toString()); } }
正在添加元素0
true
正在添加元素1
true
正在添加元素2
true
正在添加元素3
正在移除元素
true
true
[0, 2, 3]

浙公网安备 33010602011771号