java.util.concurrent (JUC) greatly improves the performance of concurrent, AQS is considered to be the core of the JUC.
CountdownLatch
Used to control a thread waiting for multiple threads.
It maintains a counter cnt, each call countDown () method will make counter value minus 1, when reduced to zero, because those calls await () method will be awakened in the waiting threads.
public class CountdownLatchExample { public static void main(String[] args) throws InterruptedException { final int totalThread = 10; CountDownLatch countDownLatch = new CountDownLatch(totalThread); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalThread; i++) { executorService.execute(() -> { System.out.print("run.."); countDownLatch.countDown(); }); } countDownLatch.await(); System.out.println("end"); executorService.shutdown(); } } run..run..run..run..run..run..run..run..run..run..end
CyclicBarrier
Used to control multiple threads wait for each other only when multiple threads have arrived, these threads will continue to execute.
And CountdownLatch similar, are achieved through the maintenance counter. Thread await execution after () method will counter by 1, and waits until the counter is zero, all calls await () method in the thread continues to wait.
One difference is CyclicBarrier and CountdownLatch, CyclicBarrier counter can be recycled by calling the reset () method, so it was called the circulation barrier.
CyclicBarrier has two constructors which time parties indicate that the counter initial value, barrierAction all threads have reached the barrier will be executed once.
public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } public CyclicBarrier(int parties) { this(parties, null); }
public class CyclicBarrierExample { public static void main(String[] args) { final int totalThread = 10; CyclicBarrier cyclicBarrier = new CyclicBarrier(totalThread); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalThread; i++) { executorService.execute(() -> { System.out.print("before.."); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.print("after.."); }); } executorService.shutdown(); } } before..before..before..before..before..before..before..before..before..before..after..after..after..after..after..after..after..after..after..after..
Semaphore
Semaphore 类似于操作系统中的信号量,可以控制对互斥资源的访问线程数。
以下代码模拟了对某个服务的并发请求,每次只能有 3 个客户端同时访问,请求总数为 10。
public class SemaphoreExample { public static void main(String[] args) { final int clientCount = 3; final int totalRequestCount = 10; Semaphore semaphore = new Semaphore(clientCount); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < totalRequestCount; i++) { executorService.execute(()->{ try { semaphore.acquire(); System.out.print(semaphore.availablePermits() + " "); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }); } executorService.shutdown(); } }
2 1 2 2 2 2 2 1 2 2
Free Java needs its own advanced data collection, covering Java, Redis, MongoDB, MySQL, Zookeeper, Spring Cloud, Dubbo distributed high concurrency and other tutorials, a total of 30G.
Portal: HTTPS: // mp.weixin.qq.com/s/Jzdd fH-7yNudmkjT0IRL8Q