countdownlatch

Java多线程 - CyclicBarrier原理

五迷三道 提交于 2020-02-27 10:40:58
1. 概述 现实生活中我们经常会遇到这样的情景,在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,比赛时要等运动员都上场后才开始。 在JUC包中为我们提供了一个同步工具类能够很好的 模拟 这类场景,它就是CyclicBarrier类。利用CyclicBarrier类可以实现一组线程相互等待,当所有线程都到达某个屏障点后再进行后续的操作。下图演示了这一过程。 CyclicBarrier字面意思是“可重复使用的栅栏”,CyclicBarrier 相比 CountDownLatch 来说,要简单很多,其源码没有什么高深的地方,它是 ReentrantLock 和 Condition 的组合使用。 看如下示意图,CyclicBarrier 和 CountDownLatch 是不是很像,只是 CyclicBarrier 可以有不止一个栅栏,因为它的栅栏(Barrier)可以重复使用(Cyclic) 首先,CyclicBarrier 的源码实现和 CountDownLatch 大相径庭,CountDownLatch 基于 AQS 的共享模式的使用,而 CyclicBarrier 基于 Condition 来实现的。因为 CyclicBarrier 的源码相对来说简单许多,读者只要熟悉了前面关于 Condition 的分析

JUC包中的锁框架

天大地大妈咪最大 提交于 2020-02-27 08:52:56
 JUC包中的锁,包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件,AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁。由于CountDownLatch,CyclicBarrier和Semaphore也是通过AQS来实现的;因此,我也将它们归纳到锁的框架中进行介绍。   先看看锁的框架图,如下所示。 01. Lock接口   JUC包中的 Lock 接口支持那些语义不同(重入、公平等)的锁规则。所谓语义不同,是指锁可是有"公平机制的锁"、"非公平机制的锁"、"可重入的锁"等等。"公平机制"是指"不同线程获取锁的机制是公平的",而"非公平机制"则是指"不同线程获取锁的机制是非公平的","可重入的锁"是指同一个锁能够被一个线程多次获取。 02. ReadWriteLock   ReadWriteLock 接口以和Lock类似的方式定义了一些读取者可以共享而写入者独占的锁。JUC包只有一个类实现了该接口,即 ReentrantReadWriteLock,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的

Java多线程整理

空扰寡人 提交于 2020-02-27 08:50:24
目录: 1.volatile变量 2.Java并发编程学习 3. CountDownLatch用法 4. CyclicBarrier使用 5.BlockingQueue使用 6.任务执行器Executor 7.CompletionService使用 8.ConcurrentHashMap使用 9.Lock使用 一、 volatile变量   1.volatile原理:volatile的原理实际上是告诉处理器,不要把变量缓存在寄存器或者相对于其他处理器不可见的地方,而是把变量放在主存,每次读写操作都在主存上进行操作。另外,被申明为volatile的变量也不会与其它内存中的变量进行重排序。   2.volatile同步:volatile是同步的一个子集,只保证了变量的可见性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。相对于同步而言,volatile的优势:a.简易性,可以像使用其他变量一样使用volatile变量;b.volatile变量不会造成线程阻塞;c.如果读操作远远大于写操作,volatile 变量还可以提供优于锁的性能优势。   3.正确使用volatile条件:对变量的写操作不依赖于当前值;该变量没有包含在具有其他变量的不变式中; /* * 对于第一条原则:对变量的写操作不依赖于当前值; * 虽然i++只有一条语句

多线程同步的三大神器

萝らか妹 提交于 2020-02-18 11:12:39
本文出自 代码大湿 代码大湿 实现多个线程同步一般有三种方式(CountDownLatch,CyclicBarrier,Semaphore) 1:CountDownLatch一般用于一个线程等待其他多个线程的同步。其countDown方法将计数器减1。await方法在计数器不为0的时候都是阻塞状态(await不改变计数器的值)。 2:CyclicBarrier的await将计数器值加1,其值不为构造器中的参数的时候是阻塞的。而且CyclicBarrier还可以重复利用。等到计数器为0的时候开始执行。 3: Semaphore(信号量)是实现多线程的资源共享。 看CountDownLatch的例子: package demo; import java.util.concurrent.CountDownLatch; public class Main { public static void main(String[] args) { CountDownLatch countDownLatch=new CountDownLatch(5); for(int i=0;i<5;i++){ new Thread(new r(countDownLatch)).start(); } try { countDownLatch.await(); System.out.println("主线程可以执行了

线程同步器CountDownLatch

邮差的信 提交于 2020-02-16 13:37:59
  Java程序有的时候在主线程中会创建多个线程去执行任务,然后在主线程执行完毕之前,把所有线程的任务进行汇总,以前可以用线程的join方法,但是这个方法不够灵活,我们可以使用CountDownLatch类,实现更优雅,而且使用线程池的话,可没有办法调用线程的join方法的呀! 一.简单使用CountDownLatch   直接使用线程: package com.example.demo.study; import java.util.concurrent.CountDownLatch; public class Study0215 { //这里相当于新建一个初始值为2的计数器 private static volatile CountDownLatch countDownLatch = new CountDownLatch(2); public static void main(String[] args) throws InterruptedException { new Thread(()->{ try { Thread.sleep(1000); System.out.println("线程一执行完毕"); } catch (Exception e) { }finally { //每调用这个方法计数器减一 countDownLatch.countDown(); } })

CyclicBarrier的使用

孤人 提交于 2020-02-11 06:47:10
简介 CyclicBarrier翻译过来就是循环门闩的意思,CyclicBarrier类不仅有CountDownLatch所具有的功能,还可以实现屏障等待的功能,也就是阶段性同步,它在使用上的意义在于可以循环地实现线程要一起做任务的目标,而不是像CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性,API结构如下: CyclicBarrier类和Semaphore及CountDownLatch一样,也是一个同步辅助类。它允许一组线程互相等待,直到到达某个公共屏障点,这些线程必须实时地等待,这种情况下就可以使用CyclicBarrier类来方便地实现这样的功能,CyclicBarrier的公共屏障点可以重用。 CyclicBarrier和CountDownLatch的区别: 1、CountDownLatch作用:一个线程或者多个线程,等待另外一个线程或多个线程完成某个事情之后才能继续执行 2、CyclicBarrier的作用:多个线程之间相互等待,任何一个线程完成之前,所有的线程都必须等待,所以对于CyclicBarrier来说,重点是“多个线程之间”任何一个线程没有完成任务,则所有线程都必须等待。 CountDownLatch和CyclicBarrier都有等待的功能,CountDownLatch是两个角色之间互相等待,而CyclicBarrier是同类互相等待

Semaphore

假装没事ソ 提交于 2020-02-08 12:35:20
背景 Semaphore 用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。信号量还可以用来实现某种资源池,或者对容器施加边界。 Semaphore 管理着一组许可(permit),许可的初始数量可以通过构造函数设定,操作时要首先获得许可,才能进行操作,操作完成之后释放许可。如果没有获取许可,则阻塞直到有许可被释放。如果初始化一个许可为 1 的 Semaphore 那就相当于初始化了一个不可重入的互斥锁。 源码分析 构造函数 public Semaphore(int permits) { sync = new NonfairSync(permits); } public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); } 两个构造方法都必须提供许可数量。第二个构造用法用于指定公平模式还是非公平模式。与 ReentrantLock 中的公平锁和非公平锁一样。公平信号量获取时,如果当前线程不在 CLH 队列的头部,则需要排队等候,对于非公平信号量而言,无论当前线程处于 CLH 队列的任何位置都可以直接获取。 获取许可 Semaphore 提供了四种获取许可的方法,分别如下: //获取一个许可证(响应中断)

Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

半城伤御伤魂 提交于 2020-02-08 00:16:41
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。 以下是本文目录大纲: 一.CountDownLatch用法 二.CyclicBarrier用法 三.Semaphore用法 若有不正之处请多多谅解,并欢迎批评指正。 一.CountDownLatch用法 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。 CountDownLatch类只提供了一个构造器: public CountDownLatch(int count) { }; //参数count为计数值 然后下面这3个方法是CountDownLatch类中最重要的方法: public void await() throws InterruptedException { }; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException

Java 并发包中的高级同步工具

送分小仙女□ 提交于 2020-02-07 14:53:54
Java 并发包中的高级同步工具 Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提供了各种功能支持,比如: 提供了线程池的创建类 ThreadPoolExecutor、Executors 等; 提供了各种锁,如 Lock、ReentrantLock 等; 提供了各种线程安全的数据结构,如 ConcurrentHashMap、LinkedBlockingQueue、DelayQueue 等; 提供了更加高级的线程同步结构,如 CountDownLatch、CyclicBarrier、Semaphore 等。 在前面的章节中我们已经详细地介绍了线程池的使用、线程安全的数据结构等,本文我们就重点学习一下 Java 并发包中更高级的线程同步类:CountDownLatch、CyclicBarrier、Semaphore 和 Phaser 等。 CountDownLatch 介绍和使用 CountDownLatch(闭锁)可以看作一个只能做减法的计数器,可以让一个或多个线程等待执行。 CountDownLatch 有两个重要的方法: countDown():使计数器减 1; await():当计数器不为 0 时,则调用该方法的线程阻塞,当计数器为 0 时,可以唤醒等待的一个或者全部线程。

CountDownLatch的使用

試著忘記壹切 提交于 2020-02-06 18:15:02
简介 Latch即为门闩的意思,它所表达的意思是:当门没有打开时,所有的人都无法进入,即所有的线程也无所谓继续向下运行,这样可以控制线程执行任务的时机,使线程可以以组团的方式一起执行任务,CountDownLatch类所提供的功能是判断count计数不为0时,当前线程是wait状态,即都处于阻塞等待。同时CountDownLatch类也是一个具有同步功能的辅助类,使用效果是 给定一个计数,当时用这个CountDownLatch类的线程判断计数不为0时,则呈wait状态,如果为0时则继续运行。实现等待和继续运行的效果分别需要使用await()和countDown()方法来进行。调用await()方法时判断计数是否为0,如果不为0则呈等待状态。其他线程可以调用countDown()方法将计数减1,当计数减到0时,呈等待状态的线程继续运行。而方法getCount()就是获得当前的计数个数,需要注意的是,计数值无法被重置,计数是减法操作 API使用 1.1、await()以及countDwon()方法的使用 案例 public class MyService { //创建1个计数的实例 private CountDownLatch downLatch = new CountDownLatch ( 1 ) ; public void testMethod ( ) { try { System