多线程分配线程的实现方案:CountDownLatch类
需求:假如我们本地有4个文件需要解析,每个文件的内容为20万行。为了提高效率我们要创建4个线程进行处理。等4个线程处理完,要在文件日志表中记录处理状态。
一般的的解决方法是使用join,join用于让当前执行线程等待join线程执行结束。其实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远wait。直到join线程中止后,线程的this.notifyAll会被调用。
但是DK1.5之后的并发包中提供的CountDownLatch也可以实现join的这个功能,并且比join的功能更多。
public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(4);
/**线程记录数,当线程开始调用时主线程阻塞,每当一个线程结束时调用countDown()方法,线程记录数减一,当线程记录数为0时,主线程恢复调用。***/
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(1);
c.countDown();//记录数减一,3
System.out.println(2);
c.countDown();//记录数减一,2
System.out.println(3);
c.countDown();//记录数减一,1
System.out.println(4);
c.countDown();//记录数减一,0
}
}).start();
c.await();
System.out.println("主线程调用");//开始调用日志记录
}
}
CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。
当我们调用一次CountDownLatch的countDown方法时,N就会减1,CountDownLatch的await会阻塞当前线程,直到N变成零。由于countDown方法可以用在任何地方,所以这里说的N个点,可以是N个线程,也可以是1个线程里的N个执行步骤。用在多个线程时,你只需要把这个CountDownLatch的引用传递到线程里。
/**
* 单个文件处理入库
* @author yanjp
*
*/
class Worker extends Thread{
private DyFile dyFile;
private CountDownLatch ct;
private AnalyzeFileService analyzeFileService;
public Worker(AnalyzeFileService analyzeFileService ,DyFile dyFile,CountDownLatch ct){
this.dyFile=dyFile;
this.ct=ct;
this.analyzeFileService=analyzeFileService;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
logger.info("begin入库处理文件:"+dyFile.getFileName());
//合适的处理器,处理文件.
analyzeFileService.analyze(dyFile);
logger.info("end入库处理文件:"+dyFile.getFileName());
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error("单个文件入库处理异常",e);
}finally{
//完成一件任务
ct.countDown();
}
} }
如果有某个解析sheet的线程处理的比较慢,我们不可能让主线程一直等待,所以我们可以使用另外一个带指定时间的await方法,await(long time, TimeUnit unit): 这个方法等待特定时间后,就会不再阻塞当前线程。join也有类似的方法。
注意:计数器必须大于等于0,只是等于0时候,计数器就是零,调用await方法时不会阻塞当前线程。CountDownLatch不可能重新初始化或者修改CountDownLatch对象的内部计数器的值。一个线程调用countDown方法 happen-before 另外一个线程调用await方法。
CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。
参考:
http://ifeve.com/talk-concurrency-countdownlatch/
多线程分配线程的实现方案:CountDownLatch类的更多相关文章
- 关于Unity中协程、多线程、线程锁、www网络类的使用
协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...
- 多线程-2.线程创建方式和Thread类
线程的创建方式 1.继承Thread类,重写run方法,示例如下: 1 class PrimeThread extends Thread { 2 long minPrime; 3 PrimeThrea ...
- java核心-多线程(4)-线程类基础知识
1.并发 <1>使用并发的一个重要原因是提高执行效率.由于I/O等情况阻塞,单个任务并不能充分利用CPU时间.所以在单处理器的机器上也应该使用并发. <2>为了实现并发,操作系 ...
- java多线程等待协调工作:CountDownLatch类的高级应用
一:说明 基本上对于线程初步了解的人,都是使用synchronized来同步线程的,也确实,它也是可以满足一些常用的问题.那么我们来说一些它不能解决的问题(其实是不怎么好解决的问题,并不是真的不能解决 ...
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)
多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...
- python 多线程编程之threading模块(Thread类)创建线程的三种方法
摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- Java多线程之线程其他类
Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...
随机推荐
- Delphi 使用Tabel组件的记录查找
樊伟胜
- Linux Shell Web超级终端工具shellinabox
Shell是Linux内核应用程序,是指“为使用者提供操作界面”的软件,也是命令解析器,它类似于Windows操作系统DOS下的cmd.exe应用程序.它接收用户命令,然后调用相应的应用程序,用户一般 ...
- service worker 实现页面通信
sw.js 基本写法: function send_message_to_sw(msg){ navigator.serviceWorker.controller.postMessage("C ...
- QTP(6)
一.检查点 1.标准检查点(Standard Checkpoint) 作用:检查对象的属性值是否正确 文本框对象:text 预期值 单选按钮对象:checked ON/OFF 下拉框对象:Select ...
- notepad++ 二进制插件
https://jingyan.baidu.com/article/6fb756ec457aca241858fba6.html winhex
- p1268树的重量 题解
题面描述点此qwq. 正解开始. 一道茅塞顿开恍然大悟的题目: 第一眼看到这个题的时候,语文不好的我对着题目中的 这些,和: 这句话发呆半天,,,, 因为不关我怎么构建几何模型,我都不理解这句话.. ...
- C#工具:ASP.net 调用MySQL 帮助类(包括存储过程调用)
1.创建DbHelperMySQL类 2.复制代码到类中 using System; using System.Collections; using System.Collections.Specia ...
- TETP服务和PXE功能
PXE PXE:Preboot Excution Environment, Intel公司研发,没有任何操作系统的主机,能够基于网络完成系统的安装工作.
- Linux常用命令之info、cal、echo命令
info命令,是Linux下info格式的帮助指令 执行man info可以查看info命令的 语法 info(选项)(参数) 选项 -d:添加包含info格式帮助文档的目录: -f:指定要读取的in ...
- 锁&lock与latch
锁是数据库系统区别于文件系统的一个关键特性.锁机制用于管理对共享资源的并发访问.Innodb不仅仅使用行锁,也会在数据库内部其它地方使用锁,从而允许对多种不同资源提供并发访问.如:操作缓冲池中的LRU ...