一、概念 闭锁是一个同步工具类,主要用于等待其他线程活动结束后,再执行后续的操作。例如:在王者荣耀游戏中,需要10名玩家都准备就绪后,游戏才能开始。 CountDownLatch是concurrent包中的一个类,是一种灵活的闭锁实现。他可以使一个或多个线程等待一组事件的发生。闭锁状态包括一个计数器,表示需要等待的数量。 ”是为了10个线程能够同时执行,如果没有“开始闭锁”,那么在循环时,前面的线程会先执行。 设置“开始闭锁”以后,10个线程均在await方法等待。当“开始闭锁”执行countDown方法时,计时器为0,10个线程的await方法同时释放,执行后续操作。 随后主线程“结束闭锁”进行await等待,由于“结束闭锁”的计数器值为10,所以10个线程都执行countDown以后,计数器值才为0,这时“结束闭锁”await方法释放,执行以下操作。
CountDownLatch实际上是一种闭锁实现。闭锁:是一种同步工具类,可以延迟线程的进度知道其到达终止状态——《Java并发编程实战》。这个怎么解释呢? 简单来说,就是有1个线程需要等待其余10个线程都执行完毕后再执行,这个时候就可以使用闭锁,也即CountDownLatch(当然闭锁的实现并不止这一种)。 关于对闭锁的详细解释请参考《Java并发编程实战》P79。 CountDownLatch中有一个计数器,该计数器通过构造方法传递,表示需要完成的工作。 1 package countdownlatch; 2 3 import java.util.concurrent.CountDownLatch; 4 5 /** 6 * Created 1 package countdownlatch; 2 3 import java.util.concurrent.CountDownLatch; 4 5 /** 6 * Created
闭锁的作用相当于一扇门∶ 在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。 当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。闭锁可以用来确保某些活动直到其他活动都完成后才继续执行,例如∶ 确保某个计算在其需要的所有资源都被初始化之后才继续执行。 二元闭锁(包括两个状态)可以用来表示"资源R已经被初始化",而所有需要 R 的操作都必须先在这个闭锁上等待。 确保某个服务在其依赖的所有其他服务都已经启动之后才启动。每个服务都有一个相关的二元闭锁。 当启动服务S 时,将首先在S依赖的其他服务的闭锁上等待,在所有依赖的服务都启动后会释放闭锁S,这样其他依赖 S 的服务才能继续执行。 num.incrementAndGet())); System.out.println("cost time: " + time + "ms"); } } //输出结果 1 10 9 8 7 5 6 4 3 2
run() { //遍历50000,当计算到为偶数,则打印 for (int i = 0; i < 50000; i++) { if (i % 2 == 0) { System.out.println(i); } } } } 2.创建5个线程执行,并且统计所有线程的运行时长 - 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完成才继续执行: - 确保某个计算在其需要的所有资源都被初始化之后才继续执行; - 确保某个服务在其依赖的所有其他服务都已经启动之后才启动 //遍历50000,当计算到为偶数,则打印 for (int i = 0; i < 50000; i++) { if (i % 2 finally { //递减闭关锁的count次数,当count=0,则结束闭关锁 latch.countDown(); } } } 2.
java闭锁用于多个线程共同执行后,统一执行一个动作。比如:多个线程执行计算操作,最后汇总到同一个线程执行汇总计算。需要注意的是,java中的闭锁是仅一次的。当闭锁打开后就会统一执行下面的动作。 static void main(String[] args) throws ExecutionException, InterruptedException { /** * 闭锁 WorkerWithResult(downLatch, 1)); Future<Integer> future1 = executor.submit(new WorkerWithResult(downLatch, 2) ); Future<Integer> future2 = executor.submit(new WorkerWithResult(downLatch, 3)); FutureTask workTimeList.add(future); workTimeList.add(future1); workTimeList.add(future2)
import org.springframework.web.bind.annotation.RestController; /** * @author: xiepanpan * @Date: 2020/2/ org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author: xiepanpan * @Date: 2020/2/
摘要 本文主要介绍Java多线程并发中闭锁(Latch)的基本概念、原理、实例代码、应用场景,通过学习,可以掌握多线程并发时闭锁(Latch)的使用方法。 闭锁(Latch),目的是使多个线程在完成各自任务后,才会打开继续执行后面的任务,否则一直等待。 计数器闭锁(CountDownLatch)是一个同步工具类, 可以用来协调多个线程的执行时间,允许一个或多个线程等待某个事件的发生。 ); 2、 其他每个线程在各自执行完毕时, 分别调用一次countDown())方法,用来递减计数器, 表示有一个线程已经执行完毕了;这时, 线程a可以调用await()方法, 用来等待计数器的值为0。 2、确保某个服务,在其依赖的所有其他服务都已经启动后再启动。 3、确保某个任务,在所有参与者都准备就绪后再执行,比如:线上上课,在全班30个同学都全部上线后,老师才能开始上课。 ?
rockchip\rk356x\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml 在这个文件中修改 关闭锁屏
如果取消(释放)则用到了这个方法,这个方法执行一次,那么总数(构造方法中的参数count)就会减去1, 直到构造参数是0时,该管理器结束,不再闭锁其他线程。
许多闭锁患者可以通过有意识的眼球运动和眨眼进行交流,但也有一些患者完全不能动弹,甚至连眼球或眼睑都不能动弹,这样一来,"如果你听懂了,就眨两下眼睛"的指令就变得毫无意义。 这些方法虽然前景广阔,但通常都是侵入性的、费力的、昂贵的,专家们一致认为,要让闭锁病人发出声音,还需要进行更多的研究开发。 # 让大脑参与--但在哪里? 构建脑机接口的第一步是决定利用大脑的哪个部分。 最终,让闭锁患者恢复语言的最大挑战可能更多地与生物学有关,而不是技术。语音编码的方式,特别是内部语音,可能因个人或情况而异。
1 package futuretask; 2 3 import java.util.concurrent.Callable; 4 5 /** 6 * Created by yulinfeng 通过多线程的方式创建线程: 1 package futuretask; 2 3 import countdownlatch.TaskThread; 4 5 import java.util.concurrent 直接创建线程: 1 package futuretask; 2 3 import countdownlatch.TaskThread; 4 5 import java.util.concurrent 其实和我们上一节将的CountDownLatch一样,它也是一种闭锁的实现。
文章目录 脑图 CountDownLatch闭锁 示例 Thread#join() CountDownLatch CountDownLatch示例二 await一直等待其他线程执行完 CountDownLatch ---- CountDownLatch闭锁 Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能。 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完成才继续执行: 确保某个计算在其需要的所有资源都被初始化之后才继续执行; 确保某个服务在其依赖的所有其他服务都已经启动之后才启动 JDK里看不到 log.info("t1 t2 完成,继续其他操作"); } } 输出: ? ); // 开启线程 t1.start(); t2.start(); // 主线程调用await方法 ,等待t1 t2 完成后继续操作。
CountDownLatch 闭锁 CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 闭锁可以延迟线程的进度直到其达到终止状态 闭锁可以用来确保某些活动直到其他活动都完成之后才继续执行: a) 确保某个计算在其需要的所有资源都被初始化之后才继续执行; b) 确保某个服务在其依赖的所有其他服务都已经启动之后才启动 this) { try { for (int i = 0; i < 5000; i++) { if(i % 2 finally { // 计数器减一 latch.countDown(); } } } } 2. FutureTask FutureTask相信大家也不陌生了,它是一种闭锁。
CountDownLunch countDownLunch,又叫闭锁。 它有三个关键的api: new CountDownLatch(count); 创建一个闭锁,并声明count的值 countDownLatch.await();如果countDownLunch的count logger = LoggerFactory.getLogger(this.getClass()); CyclicBarrier cyclicBarrier = new CyclicBarrier(2, logger.info("cyclicBarrier被置为0了,{}",Thread.currentThread().getName()); }); logger.info("cyclicBarrier初始化为2, 从日志中可以看出,线程123都顺利的拿到了资源,但是线程45在申请资源时发生了阻塞,当t1释放资源时,t4先获取到资源,t2释放资源时,t5获取到了资源。
从火箭发场景来学习Java多线程并发闭锁对象 倒计时器场景 在我们开发过程中,有时候会使用到倒计时计数器。最简单的是:int size = 5; 执行后,size—这种方式来实现。 然后再闭锁上等待的其他线程就可以恢复正常工作了。
Semaphore翻译成字面意思为 信号量,Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可 CountDownLatch:闭锁 CountDownLatch也常常被我们称为闭锁,是JUC提供给我们算是比较常用的一个工具了。 当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。 使用场景: 实现最大并行性:注意不是并发,是并行。并行强调的是所有人同一时刻统一开始。 妈妈挤公交去饭店需要2小时。 我乘地铁去饭店需要1小时。 一家人到齐了,开始吃饭 我们发现,光集合就花了6个小时。 一家人到齐了,开始吃饭 妈妈挤公交去饭店需要2小时。 我乘地铁去饭店需要1小时。 这个好像也不行,人还没到齐就开饭了。
闭锁:CountDownLatch 1.1 使用场景 若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁。 1.2 代码实现 // 初始化闭锁,并设置资源个数 CountDownLatch latch = new CountDownLatch(2); Thread t1 = new Thread( new latch.countDown(); } } ).start(); Thread t2 = new Thread( new Runnable(){ public void run(){ // 加载资源2 资源加载代码…… // 本资源加载完后,闭锁-1 latch.countDown(); } } ).start 0时,await返回,执行接下来的任务 任务代码…… } } ).start(); 2.
闭锁 闭锁是一种同步工具类,可以延迟线程进度直到其到达终止状态。闭锁的作用相当于一扇门,闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当结束时,这扇门会打开,并且允许所有线程通过。 FutureTask来加速执行 public T someMethod(){ FutureTask<T> task1= new FutureTask(....); FutureTask<T> task2= FutureTask<T> task3= new FutureTask(....); executor.submit(task1); executor.submit(task2) ; executor.submit(task3); try{ task1.get(); task2.get(); task3.get(); 栅栏 栅栏类似于闭锁,能阻塞一组线程知道某个事件发生。 区别:栅栏与闭锁关键区别在于所有线程必须同时到达栅栏位置,才能继续执行。
闭锁闭锁 是一种同步工具类,它可以延迟线程的进度直到其到达终止状态。 二元闭锁(包括两个状态)可以用来表示“资源 R 已经被初始化”,而所有需要R的操作都必须先在这个闭锁上等待。确保某个服务在其依赖的所有其他服务都已经启动之后才启动。每个服务都有一个相关的二元闭锁。 2. FutureTaskFutureTask 也可以用作闭锁。 } } } private Board computeValue(int x, int y) { x = 2 * x + y; y = 2 * y + x; return new Board(x, y); } } public void start
同步工具类图: 闭锁相关:CountDownLatch 信号量相关:Semaphore 栅栏相关:CyclicBarrier 、Exchanger 线程池相关:Executors 闭锁 闭锁是一种工具同步类 闭锁的作用相当于一道门,在闭锁到达结束状态之前,这扇门一直是关闭的,没有线程可以通过;当闭锁结束时,这扇门会打开所有线程可以通过。当闭锁达到结束状态打开门时,将不会再改变其状态,即门不会再次关闭。 CountDownLatch是一种灵活的闭锁实现,可以在上述各种情况下使用,它可以使一个或多个线程等待一组事件的发生。闭锁状态包括一个计数器,计数器被初始化为一个正数,表示需要等待的事件数量。 如果不适用闭锁,先启动的线程必将领先后启动的线程。 信号量Semaphore 计数信号量用来控制同时访问某个特定资源的操作数量,或者同时指定某个特定操作的数量。 栅栏与闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,栅栏用于等待其他线程。 常见的栅栏有两种形式:CyclicBarrier和Exchanger。