做美食网站视频,四川成都网站制作,上海 微信网站 建站,专业网站建设教程之所以把Latch与Barrier放在一起比较是因为他们给人一种相似的感觉。他们都是阻塞一些行为直至某个事件发生#xff0c;但Latch是等待某个事件发生#xff0c;而Barrier是等待线程。先比较一下JCIP中对二者的描述#xff1a;LatchA latch is a synchronizer that can delay …之所以把Latch与Barrier放在一起比较是因为他们给人一种相似的感觉。他们都是阻塞一些行为直至某个事件发生但Latch是等待某个事件发生而Barrier是等待线程。先比较一下JCIP中对二者的描述LatchA latch is a synchronizer that can delay the progress of threads until it reaches its terminal state.A latch acts as a gate: until the latch reaches the terminal state the gate is closed and no thread can pass, and in the terminal state the gate opens, allowing all threads to pass.Once the latch reaches the terminal state, it cannot change state again, so it remains open forever.Latches can be used to ensure that certain activities do not proceed until other one-time activities complete。即闭锁可以延迟线程执行直至达到相应的结束状态。闭锁就像一个大门未到达结束状态相当于大门紧闭不让任何线程通过。而到达结束状态后大门敞开让所有的线程通过但是一旦敞开后不会再关闭。闭锁可以用来确保一些活动在某个事件发生后执行。BarrierCyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel iterative algorithms that break down a problem into a fixed number of independent subproblems.Threads call await when they reach the barrier point, and await blocks until all the threads have reached the barrier point.If all threads meet at the barrier point, the barrier has been successfully passed, in which case all threads are released and the barrier is reset so it can be used again.很多人都把Barrier直译为栅栏我也很喜欢这个叫法。栅栏可以使一组执行在一处汇集也就是说我们可以用栅栏将一个问题分解成多个独立的子问题并在执行结束后在同一处进行汇集。当线程到达汇集地后调用awaitawait方法会出现阻塞直至其他线程也到达汇集地。如果所有的线程都到达就可以通过栅栏也就是所有的线程得到释放而且栅栏也可以被重新利用。另外下面javadoc中对二者之间区别的说明A CountDownLatch is initialized with a given count.The await methods block until the current count reaches zero due to invocations of the countDown method, after which all waiting threads are released and any subsequent invocations of await return immediately.This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.闭锁从来都是带着事件的触发次数。await方法会一直阻塞至countDown方法将次数变成0为止所有的线程被释放才能进行后续的工作。但这种现象只能出现一次也就是说触发次数不会被重置。如果你想要一个可重置次数的闭锁那就用栅栏。Another typical usage would be to divide a problem into N parts, describe each part with a Runnable that executes that portion and counts down on the latch, and queue all the Runnables to an Executor.When all sub-parts are complete, the coordinating thread will be able to pass through await.(When threads must repeatedly count down in this way, instead use a CyclicBarrier.)这种行为阻塞的典型用法之一就是将某个问题分成多个部分每个部分用不同的线程负责并记得减少闭锁设置的次数。当所有线程的工作结束后将通过await方法造成的阻塞如果我们需要反复进行这样的工作就需要使用栅栏。好了既然Doug Lea老师将同一个观点阐述了这么多遍剩下就是放心大胆地使用了也许我们将问题想得太复杂了。下面贴出栗子由一个startGate拦住所有线程的执行当所有线程就绪完成后调用countDown将它们释放而另一扇大门——endGate后面正等着计算执行时间而endGate等待的事件由这些线程触发public class TestHarness {public static long timeTasks(int nThreads, final Runnable task)throws InterruptedException {final CountDownLatch startGate new CountDownLatch(1);final CountDownLatch endGate new CountDownLatch(nThreads);for (int i 0; i nThreads; i) {Thread t new Thread() {public void run() {try {startGate.await();try {task.run();} finally {endGate.countDown();}} catch (InterruptedException ignored) {}}};t.start();}long start System.nanoTime();startGate.countDown();endGate.await();long end System.nanoTime();return end - start;}}执行看看public static void main(String[] args) throws ExecutionException, InterruptedException {System.out.println(cost :::TestHarness.timeTasks(10,new Runnable() {Overridepublic void run() {int num RandomUtils.nextInt(0,100);if(num50) try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Alvez :: num);}}));}接着试试栅栏没有搞任何复杂的东西注意countSupposed%partyCount主要是想用这个体现一下栅栏是否可以反复使用多次。如果countSupposed%partyCount的结果恰好为0所有线程执行结束后主线程也会正常结束。反之则会一直阻塞下去如果countSupposed%partyCount结果大于1且不为0其结果就是我们看到lets go to the barrier !!出现的次数public static void barrierTest(int partyCount, int countSupposed) {if(partyCount1 || countSupposed 1) throw new IllegalArgumentException();final CyclicBarrier barrier new CyclicBarrier(partyCount,new Runnable() {Overridepublic void run() {System.out.println(lets go barrier !!);}});System.out.println(countSupposed%partyCount0?lets show the smooth!!:....but blocked);for (int i 0; i countSupposed; i) {Runnable runnable new Runnable() {Overridepublic void run() {try {barrier.await();System.out.println(Thread.currentThread().getName() show!!);} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}};new Thread(runnable).start();}}执行:public static void main(String[] args) {barrierTest(11, 20);}