Java多线程——Semaphore&CyclicBarrier(信号量与同步屏障)
今天在leetcode刷了一道题,发现了新大陆,直呼妙啊!
以下为题目:
现在有两种线程,氧 oxygen 和氢 hydrogen,你的目标是组织这两种线程来产生水分子。
存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来。
氢和氧线程会被分别给予 releaseHydrogen 和 releaseOxygen 方法来允许它们突破屏障。
这些线程应该三三成组突破屏障并能立即组合产生一个水分子。
你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。
换句话说:
如果一个氧线程到达屏障时没有氢线程到达,它必须等候直到两个氢线程到达。
如果一个氢线程到达屏障时没有其它线程到达,它必须等候直到一个氧线程和另一个氢线程到达。
书写满足这些限制条件的氢、氧线程同步代码。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/building-h2o
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
以下为题解:
1 class H2O { 2 private CyclicBarrier cyclicBarrier; 3 private Semaphore hydrogen; 4 private Semaphore oxygen; 5 public H2O() { 6 this.cyclicBarrier = new CyclicBarrier(3); 7 this.hydrogen = new Semaphore(2); 8 this.oxygen = new Semaphore(1); 9 } 10 11 public void hydrogen(Runnable releaseHydrogen) throws InterruptedException { 12 hydrogen.acquire(); 13 // releaseHydrogen.run() outputs "H". Do not change or remove this line. 14 releaseHydrogen.run(); 15 try { 16 cyclicBarrier.await(); 17 hydrogen.release(); 18 } catch (BrokenBarrierException e) { 19 e.printStackTrace(); 20 } 21 } 22 23 public void oxygen(Runnable releaseOxygen) throws InterruptedException { 24 oxygen.acquire(); 25 // releaseOxygen.run() outputs "O". Do not change or remove this line. 26 releaseOxygen.run(); 27 try { 28 cyclicBarrier.await(); 29 oxygen.release(); 30 } catch (BrokenBarrierException e) { 31 e.printStackTrace(); 32 } 33 } 34 }

对于代码进行部分解释:
Semaphore为信号量,其acquire()方法为申请一个资源,使其在实例化时设定的最大资源数(初始信号量)-1,而release方法为释放一个资源使其+1;
CyclicBarrier为同步屏障,在JDK1.5被引入,可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,所以被阻塞的线程才能继续执行。CyclicBarrier好比一扇门,默认情况下关闭状态,堵住了线程执行的道路,直到所有线程都就位(执行到此行代码前),门才打开,让所有线程一起通过。其实例化时的值可以理解为,屏障处多少个线程到达时放行。其await()方法则为插入屏障。
初步了解后感叹于巧妙!感受到了兴奋与惊奇!!!(菜鸡没见过世面)

浙公网安备 33010602011771号