Latches:
A latch is a synchronizer that can delay the process 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.
Latch can be used to ensure that certain activities do not proceed until other on-time activities complete, such as:
1> Ensuring that a computation does not proceed until resources it needs have been initialized. A simple binary(two-state) latch could be used to indicate "Resource R has been initialized", and any activity that requires R would wait first on this latch.
public class CountDownLatchTest { @Test public void countDownTest1() throws InterruptedException { CountDownLatch resourcePrepareLatch = new CountDownLatch(1); ResourcePrepareThread resourcePrepareThread = new ResourcePrepareThread( resourcePrepareLatch); ResourceBlockingThread resourceBlockingThread = new ResourceBlockingThread( resourcePrepareLatch); ResourceBlockingThread resourceBlockingThread2 = new ResourceBlockingThread( resourcePrepareLatch); ResourceBlockingThread resourceBlockingThread3 = new ResourceBlockingThread( resourcePrepareLatch); ExecutorService executorService = Executors.newFixedThreadPool(4); executorService.submit(resourcePrepareThread); executorService.submit(resourceBlockingThread); executorService.submit(resourceBlockingThread2); executorService.submit(resourceBlockingThread3); executorService.shutdown(); executorService.awaitTermination(10, TimeUnit.SECONDS); } private static class ResourcePrepareThread implements Runnable { CountDownLatch resourcePrepareLatch; public ResourcePrepareThread(CountDownLatch resourcePrepareLatch) { super(); this.resourcePrepareLatch = resourcePrepareLatch; } @Override public void run() { try { System.out.println(String.format( "[%s] start to prepare resource", Thread.currentThread())); Thread.sleep((long) (3000 * Math.random())); System.out.println(String.format( "[%s] finished prepare resource", Thread.currentThread())); resourcePrepareLatch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } } private static class ResourceBlockingThread implements Runnable { CountDownLatch resourcePrepareLatch; public ResourceBlockingThread(CountDownLatch resourcePrepareLatch) { super(); this.resourcePrepareLatch = resourcePrepareLatch; } @Override public void run() { try { resourcePrepareLatch.await(); System.out.println(String.format("[%s] start to use resource", Thread.currentThread())); } catch (InterruptedException e) { e.printStackTrace(); } } } }
2> Ensuring that a service does not start until other services on which it depends have started. Each service would have an associated binary latch; starting service S would involve first waiting on the latches for other services on which S depends, and then releasing the S latch after startup completes so any services that depend on S can then proceed.
3> Waiting until all the parties involved in an activity, for instance the players in a multi-player game, are ready to proceed. In this case, the latch reaches the terminal state after all the players are ready.
public class BasketTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(10); BasketBallPlayer player1 = new BasketBallPlayer(countDownLatch, 1); BasketBallPlayer player2 = new BasketBallPlayer(countDownLatch, 2); BasketBallPlayer player3 = new BasketBallPlayer(countDownLatch, 3); BasketBallPlayer player4 = new BasketBallPlayer(countDownLatch, 4); BasketBallPlayer player5 = new BasketBallPlayer(countDownLatch, 5); BasketBallPlayer player6 = new BasketBallPlayer(countDownLatch, 6); BasketBallPlayer player7 = new BasketBallPlayer(countDownLatch, 7); BasketBallPlayer player8 = new BasketBallPlayer(countDownLatch, 8); BasketBallPlayer player9 = new BasketBallPlayer(countDownLatch, 9); BasketBallPlayer player10 = new BasketBallPlayer(countDownLatch, 10); ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.submit(player1); executorService.submit(player2); executorService.submit(player3); executorService.submit(player4); executorService.submit(player5); executorService.submit(player6); executorService.submit(player7); executorService.submit(player8); executorService.submit(player9); executorService.submit(player10); countDownLatch.await(); System.out.println("All player is ready. Game is starting..."); System.exit(0); } private static class BasketBallPlayer implements Runnable { CountDownLatch countDownLatch; int playerNo; public BasketBallPlayer(CountDownLatch countDownLatch, int playerNo) { super(); this.countDownLatch = countDownLatch; this.playerNo = playerNo; } @Override public void run() { try { System.out.println(String.format( "Player: [%d] start to prepare for game", playerNo)); Thread.sleep((long) (1000 * Math.random())); System.out.println(String.format( "Player: [%d] finished prepare for game", playerNo)); countDownLatch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Barriers:
We have seen how latches can facilitate starting up a group of related activities or waiting for a group of related activities to complete. Latches are single use objects, once a latches enters the terminal state, it cannot be reset.
Barriers are similars to latches in that they block a group of threads until some event has occurred. The key difference is that with a barrier, all the threads must come together at a barrier point at the same time in order to proceed. Latches are for waiting for events, barriers are for waiting for other threads.
CyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel interactive algorithms that break down a problem into a fixed number of independent subproblems. Thread 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. CyclicBarrier also lets you pass a barrier action to the constructor, this is a Runnable that is executed(in one of the subtask threads) when the barrier is successfully passed but before the blocked threads are released.
public class BarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out .println("All attendees are ready. Meeting is starting..."); } }); Runnable attendee1 = new Attendee(cyclicBarrier); Runnable attendee2 = new Attendee(cyclicBarrier); Runnable attendee3 = new Attendee(cyclicBarrier); Thread t1 = new Thread(attendee1); Thread t2 = new Thread(attendee2); Thread t3 = new Thread(attendee3); t1.start(); t2.start(); t3.start(); } private static class Attendee implements Runnable { private final CyclicBarrier cyclicBarrier; public Attendee(CyclicBarrier cyclicBarrier) { super(); this.cyclicBarrier = cyclicBarrier; } @Override public void run() { try { while (true) { System.out.println(String.format( "[%s] start to prepare for metting", Thread.currentThread())); Thread.sleep((long) (1000 * Math.random())); System.out.println(String.format( "[%s] finished prepare for metting", Thread.currentThread())); cyclicBarrier.await(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }
Reference Links:
1> "Java Concurrency in Practice"
相关推荐
C++11引入了并发编程的支持,包括`std::future`、`std::promise`以及`std::async`等工具,而`concurrency::task`是微软的PPL(Parallel Patterns Library,并行模式库)的一部分,为C++提供了更高级别的异步编程模型...
Java Concurrency in Practice 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者...
本教程"JavaConcurrency:Java并发教程"旨在深入探讨Java平台上的并发机制和最佳实践。 Java并发的核心概念包括线程、同步、互斥、死锁以及线程安全。在Java中,线程是并发执行的基本单元,通过创建Thread对象或者...
<<java并行编程>>英文版chm格式,英文名称<Java Concurrency in Practice>,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...
《Java并发编程实践》是Java开发者必读的经典之作,由Brian Goetz等多位专家共同撰写。这本书深入浅出地探讨了Java平台上的并发问题,帮助读者理解和掌握如何编写高效、可靠且可维护的多线程应用程序。以下是该书...
Using the concurrency building blocks in java.util.concurrent Performance optimization dos and don'ts Testing concurrent programs Advanced topics such as atomic variables, nonblocking algorithms, ...
The Ins and Outs of Concurrency Control
《并发的艺术》(The Art of Concurrency: A Thread Monkey's Guide to Writing Parallel Applications)是一本面向程序员的专业书籍,旨在深入讲解并发编程的核心概念和技术。本书由Clay Breshears撰写,并于2009年...
Java Concurrency in practice
Java Concurrency in Practice JAVA并发编程实践中文版(全)第二部分
《Java并发编程实践》(Java Concurrency in Practice)是一本深度探讨Java多线程和并发编程的经典著作。这本书由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著,旨在帮助Java开发者理解和解决...
《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和Doug Lea等专家共同编写。这本书深入探讨了Java平台上的多线程和并发编程,旨在...
学习java多线程必读之书。书中列举多种多线程编程的反模式,并深入讲解了JDK5中current库的用法,堪称经典!Java Concurrency In Practice PDF版本和htm版。正规PDF版本的
Get an easy introduction to reactive streams in Java to handle concurrency, data streams, and the propagation of change in today's applications. This compact book includes in-depth introductions to ...
java8 源码 并发操作合集 这是一个关于并发的系列。以实战为驱动,了解并发编程中的那些骚操作。文中的示例代码和部分解释来源于网络,你可以把这个系列当做一本工具书,想不起来的时候来看一看,顺便star一发也是...
本项目"Java-Concurrency:Java并发学习演示"旨在提供一个深入理解Java并发机制的实践平台。以下是对相关知识点的详细说明: 1. **线程与进程**:在计算机系统中,进程是资源分配的基本单位,而线程是执行的基本单位...
java concurrency in practice 经典的多线程编程书籍,英文版
Java并发编程是Java平台的核心特性之一,它使得开发者可以创建能够充分利用多核处理器能力的高效应用程序。本课程将深入探讨Java中的并发概念,包括基础支持和高阶API,特别是`java.util.concurrent`包中的工具。 ...