countdownlatch

java.util.concurrent中的常用组件

北战南征 提交于 2020-03-13 01:59:28
一. CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。 CountDownLatch的主要方法: 方法名称 方法作用 public CountDownLatch(int count) 构造器参数指定了计数的次数,即有几个独立的任务 public void CountDown() 当前线程调用此方法,计数减一,即其中一个任务完成 public void await() 当前线程调用此方法会一直被阻塞,直到计数为0,即所有子任务都完成了。 1: package com.wbl.test.thread.countDownLatch; 2: 3: import java.text.SimpleDateFormat; 4: import java.util.Date; 5: import

CountDownLatch 处理多线程问题

狂风中的少年 提交于 2020-03-12 03:57:46
多线程问题记录(自己的理解) // 主线程及 待处理的数据 List < User > users = 业务处理后形成的集合 // CountDownLatch 用来处理多线程等待问题,如 主线程 -> 多线程 -> 等待多线程全部执行完成 -> 主线程 // 初始化计数器 CountDownLatch downLatch = new CountDownLatch ( users . size ( ) ) ; // 开启多线程任务 users . forEach ( user - > { new Thread ( new Runnable ( ) { @Override public void run ( ) { System . out . println ( "当前线程:" +  Thread . currentThread ( ) . getName ( ) ) ; try { // user的业务处理方法 . . . . . . } catch ( Exception e ) { e . printStackTrace ( ) ; } finally { downLatch . countDown ( ) ; // 执行结束后计数器减 1 , 计数器结束后多线程任务结束 // 此方法最好放finally内部, 不然上面user业务代码异常后可能导致 // downLatch

java线程并发工具类

半世苍凉 提交于 2020-03-11 09:16:38
  本次内容主要讲 Fork-Join、 CountDownLatch、CyclicBarrier以及Callable、Future和FutureTask,最后再手写一个自己的FutureTask,绝对干货满满! 1、 Fork-Join 1.1 什么是 Fork-Join    Java多线程的开发可以我们自己启用多线程,线程池,还可以使用forkjoin。forkjoin可以让我们不去了解诸如Thread、Runnable等相关的知识,只要遵循forkjoin的开发模式,就可以写出很好的多线程并发程序。    forkjoin采用的是分而治之。分而治之思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。分而治之的策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为m个规模较小的子问题, 这些子问题互相独立且与原问题形式相同 ( 子问题相互之间有联系就会变为动态规范算法 ) ,递归地解这些子问题,然后将各子问题的解合并得到原问题的解,这种算法设计策略叫做分治法。用一张图来表示forkjoin原理。    我们可以了解一下计算机的十大经典算法: 快速排序、 堆排序、 归并排序 、二分查找、 BFPRT(线性查找)、DFS(深度优先搜索)、 BFS(广度优先搜索)、 Dijkstra、动态规划

JDK并发包

北城以北 提交于 2020-03-06 10:30:21
1.重入锁(ReentrantLock) 重入锁使用java.util.concurrent.locks.ReentrantLock类来实现,具有与synchronized关键字相似的功能。 1 package com.company; 2 3 import java.util.concurrent.locks.ReentrantLock; 4 5 public class User implements Runnable { 6 private ReentrantLock lock = new ReentrantLock(); 7 static int i = 0; 8 @Override 9 public void run() { 10 lock.lock(); 11 for (int j = 0; j < 10000000; j++) { 12 i++; 13 } 14 System.out.println(i); 15 lock.unlock(); 16 } 17 18 public static void main(String[] args) throws InterruptedException { 19 //注意要使用同一个对象创建线程 20 User u = new User(); 21 Thread t1 = new Thread(u); 22 Thread

CountDownLatch类 和 CyclicBarrier类 详解与区别

耗尽温柔 提交于 2020-03-04 20:12:13
1. CountDownLatch 类 CountDownLatch 类是用于线程同步的工具,作用:让一个或多个源线程(调用await方法的线程) 必须 等待一个或多个目标线程(调用countDown方法的线程)都执行完成了才能继续执行自己的代码。 注意: 1. 不会妨碍目标线程的执行,但是会阻塞源线程,因为await方法会检测count是为0,如果不是0,就会阻塞,不会继续执行后面的代码。 2. 它是一次性的,不能重复用,因为count变为0之后,就不会再改变了,只有一个countDown方法去减,没有方法去让count加,所以如果你重复使用的话,不起作用,count永远为0。 3. 当然,你可以在一个线程的run方法里调用多次countDown 方法,多减几个1。 比如一个测评系统,需要测评一个人的优秀值good,good是通过一个计算公式来计算出的,这个公式为good = 身高 + 体重 + 智力 + 情商 + 颜值,那么我们可以创建5个线程A,B,C,D,E,分别去测试出:身高、体重、智力、情商、颜值,要想计算出good,必须等待5个线程都执行完毕,身高、体重、智力、情商、颜值都得到了,才能进一步计算good。 此时CountDownLatch类就有用了。 public class CountDownLatch { // 构造方法,初始化计数值 public

JAVA JUC

非 Y 不嫁゛ 提交于 2020-03-04 03:55:54
文章目录 JAVA JUC 一、Volatile 关键字-内存可见性 1、java线程的6种状态Thread.state: 2、JAVA多线程:判断 干活 改标志位加唤醒通知(详见Thread.start()方法) 3.一共两个线程 (1)同步锁:synchronized关键字,使两个线程同步 (2)Volatile关键字 (3)Volatile与Scnchronized比较 二、原子变量与CAS算法 1、i ++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写” 2、原子变量:JDK1.5以后 java.util.concurrent.atomic 包下提供了常用的原子变量 (1)原子变量特性 (2)原子性的解决过程:(先读取内存值,再进行比较,再进行赋值和写入) (3)原子变量的使用: 三、模拟CAS算法 四、ConcurrentHashMap锁分段机制 1、hashmap和hashtable区别: 2、ConCurrentHashMap采用“锁分段”机制 3、CopyOnWriteArrayList/CopyOnWriteArraySet : “写入并复制” 4、CountDownLatch(==闭锁==,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行) 四、创建执行线程的方式三:实现Callable接口 五、Lock同步锁 1

JAVA多线程(四)--线程同步-Volatile

好久不见. 提交于 2020-03-01 07:36:10
1.cpu cache模型 cpu - 计算机的主内存(RAM), cpu速度变快,主内存没有跟上cpu的步伐,最终导致 cpu的处理速度和主内存的访问速度差距越来越大。 而cpu cache的出现解决了以上问题,同时引入了缓存不一致的问题。 比如:i++ 1)首先读取内存到cpu cache 2)进行i+1 3)将结果刷新到主内存中 在单线程中这个例子不会出现任何问题,但是在多线程的情况下就会出现问题。原因就是:每个线程都有自己的工作内存(本地内存,对应cpu cache模型中的cache),i在多个线程的本地内存中都会存在一个副本。 例:i 初始化为0;有两个操作A和B,都执行i++操作,按道理执行完之后i的值为2,但是就会有可能出现最后的结果i为1的情况,这就是缓存不一致的问题,要解决缓存不一致,我们有以下解决方式: 1)总线加锁 cpu和其他组建通信是通过总线来进行,采用总线加锁,会阻塞其他cpu对其他组件的访问,导致只有一个cpu抢到总线锁能够访问当前数据的内存。 2)通过缓存一致性协议(MESI)保证能够保证每一个缓存中使用到的共享变量副本是一致的,大致思想就是说当cpu操作cache中 的数据时,发现该数据是共享的,会进行如下操作: a. 读取操作,不用作任何处理 b. 写入操作,发出信号通知其他cpu将该变量的cache line置为无效状态

Java 并发之 CountDownLatch、CyclicBarrier 和 Semaphore

浪子不回头ぞ 提交于 2020-02-29 18:03:54
(原来写过一篇相同标题的文章,不过因为 OSChina 编辑器的缘故,格式改乱了,所以重写一篇。原文已删除,收藏原文的朋友对不住。) 这次说一下 JUC 中的同步器三个主要的成员: CountDownLatch 、 CyclicBarrier 和 Semaphore (不知道有没有初学者觉得这三个的名字不太好记)。这三个是 JUC 中较为常用的同步器,通过它们可以方便地实现很多线程之间协作的功能。(下面的代码出自 JDK 文档) CountDownLatch 直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。 作用 CountDownLatch 的作用和 Thread.join() 方法类似,可用于一组线程和另外一组线程的协作。例如,主线程在做一项工作之前需要一系列的准备工作,只有这些准备工作都完成,主线程才能继续它的工作。这些准备工作彼此独立,所以可以并发执行以提高速度。在这个场景下就可以使用 CountDownLatch 协调线程之间的调度了。在直接创建线程的年代(Java 5.0 之前),我们可以使用 Thread.join() 。在 JUC 出现后,因为线程池中的线程不能直接被引用,所以就必须使用

多线程IO操作(扫描文件夹并计算总大小)

走远了吗. 提交于 2020-02-28 11:55:02
场景为,给到一个硬盘上文件或文件夹,(当然文件夹时,多线程的优势才能越发体现出来),得到该文件或文件夹的大小和计算该结果所需要的时间。 首先是单线程下的例子,这个可难不倒大家,代码如下: public class TotalFileSizeSequential { private long getTotalSizeOfFilesInDir(final File file) { if (file.isFile()) return file.length(); final File[] children = file.listFiles(); long total = 0; if (children != null) for(final File child : children) total += getTotalSizeOfFilesInDir(child); return total; } public static void main(final String[] args) { final long start = System.nanoTime(); final long total = new TotalFileSizeSequential() .getTotalSizeOfFilesInDir(new File("D:/idea_ws")); final long

多线程进阶——JUC并发编程之CountDownLatch源码一探究竟

ぃ、小莉子 提交于 2020-02-28 11:17:32
1、学习切入点 JDK的并发包中提供了几个非常有用的并发工具类。 CountDownLatch 、 CyclicBarrier 和 Semaphore 工具类提供了一种并发流程控制的手段。本文将介绍CountDownLatch(闭锁)的实现原理。在了解闭锁之前需要先了解AQS,因为CountDownLatch的实现需要依赖于AQS共享锁的实现机制。 官方文档: https://docs.oracle.com/javase/8/docs/api/ 百度翻译如下: 一种同步辅助程序,允许一个或多个线程等待在其它线程中执行的一组操作完成。使用给定的计数初始化CountDownLatch。由于调用了countDown()方法,await方法阻塞直到当前计数为零,之后释放所有等待线程,并立即返回await的任何后续调用。这是一个一次性现象——计数不能重置。如果需要重置计数的版本,请考虑使用CyclicBarrier。倒计时锁存器是一种通用的同步工具,可用于多种目的。使用计数1初始化的倒计时锁存器用作简单的开/关锁存器或门:调用倒计时()的线程打开它之前,调用它的所有线程都在门处等待。初始化为N的倒计时锁存器可用于使一个线程等待N个线程完成某个操作或某个操作已完成N次。倒计时锁存器的一个有用特性是,它不要求调用倒计时的线程在继续之前等待计数达到零