semaphore 控制访问共享资源的最大线程数 semaphore.acquire获得许可证 semaphore.release释放许可证
下面这个代码最多运行3个打印机工作,
初始许可证的数目为3 semaphore = new Semaphore(3);
public class PrintQueue { /** * 信号量控制打印者的访问 */ private Semaphore semaphore; /** * 控制空闲打印者的数组 */ private boolean freePrinters[]; /** * 控制访问freePrinters数组的锁 */ private Lock lockPrinters; private final SimpleDateFormat sdf = new SimpleDateFormat("mm:ss.SSS"); public PrintQueue() { semaphore = new Semaphore(3); freePrinters = new boolean[3]; for (int i = 0; i < 3; i++) { freePrinters[i] = true; } lockPrinters = new ReentrantLock(); } /** * run 方法会执行这个方法 * @param document */ public void printJob(Object document) { String name = Thread.currentThread().getName(); try { // 获取信号量, 会抛出InterruptedException异常 semaphore.acquire(); System.out.println(name + " 获得信号量 at : " + sdf.format(new Date())); // 取得空闲打印者的索引 就是第几个打印机空闲 int assignedPrinter = getPrinter(); Long duration = (long) (Math.random() * 10); System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n", name, assignedPrinter, duration); TimeUnit.SECONDS.sleep(duration); // 打印工作结束后 标记为空闲 freePrinters[assignedPrinter] = true; System.out.println(semaphore.getQueueLength()); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(name + " 释放信号量 at : " + sdf.format(new Date()) + "\r\n"); semaphore.release(); } } private int getPrinter() { int ret = -1; try { // 获取锁 lockPrinters.lock(); for (int i = 0; i < freePrinters.length; i++) { if (freePrinters[i]) { ret = i; freePrinters[i] = false; break; } } } catch (Exception e) { e.printStackTrace(); } finally { lockPrinters.unlock(); } return ret; } }
最开始线程 2 3 6 获得信号量 然后 6释放信号量 这样7才获得信号量,也就是访问共享资源的线程最多就3个。![]()
countdownlatch 控制一些线程等待其他一些操作完成。比如会议,会议有12个人准备参加,countdownlatch计数器就是12,来一个人,countdown一次,主线程执行countdownlatch.await()方法,直到12人都参加会议,countdownlatch计数器为0,主线程才能继续执行下去。