Semaphore与CountDownLatch
1、Semaphore
它的作用是控制访问特定资源的线程数目,底层依赖AQS的状态state,是在生产中比较常见的一个工具类。
2、Semaphore常见API
public Semphore(int permits) public Semphore(int permits, boolean fair)
// permits表示许可的线程数量
// fair 表示公平性,如果设为true,下次执行的线程会是等待最久的线程
public void acquire() throws InterruptedException
public void release()
// acquire 获取许可
// release 释放许可
import java.util.concurrent.Semaphore; public class SemaphoreRunner { public static void main(String[] args) { Semaphore semaphore = new Semaphore(2); for (int i=0;i<5;i++){ new Thread(new Task(semaphore,"yangguo+"+i)).start(); } } static class Task extends Thread{ Semaphore semaphore; public Task(Semaphore semaphore,String tname){ this.semaphore = semaphore; this.setName(tname); } public void run() { try { semaphore.acquire(); System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis()); Thread.sleep(1000); semaphore.release(); System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
3、 CountDownLatch使用及应用场景
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成自己的任务后线程的值就会-1,当计数器的值为0时,表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
CountDownLatch.countDown(); CountDownLatch.await();
import java.util.concurrent.CountDownLatch; /** * 看大夫任务 */ public class SeeDoctorTask implements Runnable { private CountDownLatch countDownLatch; public SeeDoctorTask(CountDownLatch countDownLatch){ this.countDownLatch = countDownLatch; } public void run() { try { System.out.println("开始看医生"); Thread.sleep(3000); System.out.println("看医生结束,准备离开病房"); } catch (InterruptedException e) { e.printStackTrace(); }finally { if (countDownLatch != null) countDownLatch.countDown(); } } } import java.util.concurrent.CountDownLatch; /** * 排队的任务 */ public class QueueTask implements Runnable { private CountDownLatch countDownLatch; public QueueTask(CountDownLatch countDownLatch){ this.countDownLatch = countDownLatch; } public void run() { try { System.out.println("开始在医院药房排队买药...."); Thread.sleep(5000); System.out.println("排队成功,可以开始缴费买药"); } catch (InterruptedException e) { e.printStackTrace(); }finally { if (countDownLatch != null) countDownLatch.countDown(); } } } import java.util.concurrent.CountDownLatch; /** * 配媳妇去看病,轮到媳妇看大夫时 * 我就开始去排队准备交钱了。 */ public class CountDownLaunchRunner { public static void main(String[] args) throws InterruptedException { long now = System.currentTimeMillis(); CountDownLatch countDownLatch = new CountDownLatch(2); new Thread(new SeeDoctorTask(countDownLatch)).start(); new Thread(new QueueTask(countDownLatch)).start(); //等待线程池中的2个任务执行完毕,否则一直 countDownLatch.await(); System.out.println("over,回家 cost:"+(System.currentTimeMillis()-now)); } }
import java.util.concurrent.CyclicBarrier; public class CyclicBarrierRunner implements Runnable { private CyclicBarrier cyclicBarrier; private int index; public CyclicBarrierRunner(CyclicBarrier cyclicBarrier, int index) { this.cyclicBarrier = cyclicBarrier; this.index = index; } public void run() { try { System.out.println("index: " + index); index--; cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { CyclicBarrier cyclicBarrier = new CyclicBarrier(11, new Runnable() { public void run() { System.out.println("所有特工到达屏障,准备开始执行秘密任务"); } }); for (int i = 0; i < 10; i++) { new Thread(new CyclicBarrierRunner(cyclicBarrier, i)).start(); } cyclicBarrier.await(); System.out.println("全部到达屏障...."); } }
岁月本长而忙者自促;天地本宽而卑者自隘;风花雪月本闲,而劳忧者自冗;天行健,君子以自强不息;地势坤,君子以厚德载物;宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒.不妄取,不妄予,不妄想,不妄求,与人方便,随遇而安