`
Copperfield
  • 浏览: 260362 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
C407adc3-512e-3a03-a056-ce4607c3a3c0
java并发编程陷阱
浏览量:25138
社区版块
存档分类

并发编程陷阱系列(八)不要吞食CountDownLatch的线程异常

 
阅读更多

 之前的文章中已经介绍了无处不在的InterruptedException的处理方式了,使用CountDownLatch也会有类似的问题(正确的处理方式见下面代码: Thread.currentThread().interrupt()),顺便复习下CountDownLatch的使用方法。

 

在一些应用中,有多个线程,某个线程会在其他线程执行完毕之后才开始执行。

比如,想象有一个程序先下载一堆网页,压缩然后通过EMAIL发送出去。如果要用多线程来实现,压缩网页的程序不能在下载完成后启动。

如何处理呢?一个非常简便的方法就是使用java.util.concurrent中的CountDownLatch。

在CountDownLatch中,你可以定义一个数字,每次操作完成后数字都会减一。如果所有操作都完成了,这个数字变成0,使用同一个CountDownLatch作为同步工具的其他线程可以调用await方法完成任务。

然我们看一个简单的例子,第一个类是一个简单的Runnable。在我们的例子中,这个类没什么用处,只是采取随机休眠的方式模拟一些任务的执行。

import java.util.Random;
import java.util.concurrent.CountDownLatch;
 
public class Worker implements Runnable {
 
    private CountDownLatch countDownLatch;
 
    public Worker(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }
 
    @Override
    public void run() {
        try {
            Thread.sleep(getRandomSeconds()); // sleep random time to simulate long running task
            System.out.println("Counting down: " + Thread.currentThread().getName());
            this.countDownLatch.countDown();
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }
 
    // returns a long between 0 and 9999
    private long getRandomSeconds() {
        Random generator = new Random();
        return Math.abs(generator.nextLong() % 10000);
    }
}

 

 唯一有意思的是这一行调用:

 

this.countDownLatch.countDown();

一旦任务执行完毕,countDownLatch中的计数器就会减一。

 

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class WorkManager {
 
    private CountDownLatch countDownLatch;
    private static final int NUMBER_OF_TASKS = 5;
 
    public WorkManager() {
        countDownLatch = new CountDownLatch(NUMBER_OF_TASKS);
    }
 
    public void finishWork() {
        try {
            System.out.println("START WAITING");
            countDownLatch.await();
            System.out.println("DONE WAITING");
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }
 
    public void startWork() {
        ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_TASKS);
 
        for (int i = 0; i < NUMBER_OF_TASKS; i++) {
            Worker worker = new Worker(countDownLatch);
            executorService.execute(worker);
        }
        executorService.shutdown();
    }
 
    public static void main(String[] args) {
        WorkManager workManager = new WorkManager();
        System.out.println("START WORK");
        workManager.startWork();
        System.out.println("WORK STARTED");
        workManager.finishWork();
        System.out.println("FINISHED WORK");
    }
}

 

 

startWork方法使用ExecutorService执行Runnable类。

 

在finishWork方法中,await方法会一直等待,直到CountDownLatch内部的计数器为0时,await后的方法才会继续执行下去。

执行结果:

 

START WORK
WORK STARTED
START WAITING
Counting down: pool-1-thread-3
Counting down: pool-1-thread-4
Counting down: pool-1-thread-1
Counting down: pool-1-thread-5
Counting down: pool-1-thread-2
DONE WAITING
FINISHED WORK

 

参考:http://markusjais.com/how-to-use-java-util-concurrent-countdownlatch/

 

 

分享到:
评论

相关推荐

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段32讲、如何捕获线程运行期间的异常.mp4 │ 高并发编程第一阶段33讲、ThreadGroup API介绍之一.mp4 │ 高并发编程第一阶段34讲、ThreadGroup API介绍之二.mp4 │ 高并发编程第一阶段35讲、...

    java并发编程实战源码,java并发编程实战pdf,Java

    《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...

    Java 并发编程实战.pdf

    根据提供的信息,“Java 并发编程实战.pdf”这本书聚焦于Java并发编程的实践与应用,旨在帮助读者深入了解并掌握Java中的多线程技术及其在实际项目中的应用技巧。虽然部分内容未能提供具体章节或实例,但从标题及...

    java并发编程艺术

    此外,书中可能还会涉及其他并发编程相关的高级话题,比如原子变量(`AtomicInteger`, `AtomicReference`等)、并发工具类(如`CountDownLatch`, `CyclicBarrier`, `Semaphore`)以及Fork/Join框架。这些工具可以...

    java线程与并发编程实践

    异常处理在多线程编程中同样重要。线程的中断(interrupt())和检查中断状态(isInterrupted()、interrupted())是处理异常情况的关键。同时,当一个线程抛出未捕获异常时,会终止该线程并通知其父线程。 在《java...

    《java 并发编程实战高清PDF版》

    然而,多线程编程也带来了同步和竞态条件等问题,这需要开发者具备良好的线程管理和同步机制的知识。 书中详细讨论了Java中的线程管理,包括如何创建和启动线程,以及如何控制线程的生命周期。读者将学习到`Thread`...

    java并发编程2

    - **`java.util.concurrent` 包** 提供了丰富的并发工具类,如`ExecutorService`用于管理线程池,`Semaphore`用于许可证管理,`CountDownLatch`用于同步多个线程,`CyclicBarrier`用于多线程间的协作等。...

    并发编程之CountDownLatch

    在实际开发中,CountDownLatch 可以用来实现各种并发编程的场景,例如在多线程环境下同时启动多个线程,或者在某些特定的时刻同时启动多个线程等。下面是一个使用 CountDownLatch 实现主线程和子线程通信的示例代码...

    Java并发编程实践高清pdf及源码

    《Java并发编程实践》是一本深入探讨Java多线程编程的经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和David Holmes等专家共同编写。这本书全面介绍了Java平台上的并发编程技术,是Java开发...

    Java并发编程从入门到精通(pdf)(附源码)

    并发编程是现代软件开发中的重要组成部分,尤其是在Java这种多线程支持的语言中,理解和掌握并发编程技术至关重要。本书旨在帮助初学者快速入门,并逐步精通Java并发编程,从而提升软件性能和系统效率。 本书首先会...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段32讲、如何捕获线程运行期间的异常.mp4 │ 高并发编程第一阶段33讲、ThreadGroup API介绍之一.mp4 │ 高并发编程第一阶段34讲、ThreadGroup API介绍之二.mp4 │ 高并发编程第一阶段35讲、...

    JAVA并发编程艺术pdf版

    《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...

    Java并发编程-3.pdf

    多线程协作机制是指在多线程编程中,多个线程之间如何协作、同步和通信,以达到共同完成某个任务的目的。Java 提供了多种多线程协作机制,包括CountDownLatch、CyclicBarrier、Semaphore 等。 1. CountDownLatch ...

    java并发编程实践pdf笔记

    - `java.util.concurrent`包提供了一系列的并发工具类,如`Semaphore`(信号量)、`CountDownLatch`(计数器)、`CyclicBarrier`(回环栅栏)等,它们为复杂的并发场景提供了强大的支持。 - **并发集合** 如`...

    java并发编程实战高清版pdf

    这本书全面地介绍了Java平台上的并发和多线程编程技术,旨在帮助开发者在多核时代编写出高效、可伸缩且线程安全的代码。 并发编程是现代软件开发中的核心技能,尤其是在Java这种多线程支持的语言中更是如此。Java...

    java并发编程

    Java并发编程是Java开发者必须掌握的关键技能之一,它涉及到如何在多线程环境中高效、安全地执行程序。并发编程能够充分利用多核处理器的计算能力,提高应用程序的响应速度和整体性能。《Java编程并发实战》这本书是...

    java并发编程与实践

    在Java编程领域,并发编程是一项核心技能,尤其是在大型系统或分布式应用中,高效地处理多线程和并发操作是至关重要的。"Java并发编程与实践"文档深入剖析了这一主题,旨在帮助开发者理解和掌握如何在Java环境中有效...

    Java并发编程设计原则和模式

    在Java编程领域,并发编程是一项核心技能,尤其是在多核处理器和分布式系统中,它能显著提升应用程序的性能和响应速度。本资料“Java并发编程设计原则和模式”深入探讨了如何在Java环境中有效地进行并发处理,以充分...

    并发编程的艺术

    7. **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore等,它们在多线程协调中起到关键作用,用于控制并发流程的同步和通信。 8. **并发编程模式**:包括生产者-消费者模式、读者-写者模式、双检锁/双重...

    Java并发编程实践.pdf

    ### Java并发编程实践 #### 一、并发编程基础 ##### 1.1 并发与并行的区别 在Java并发编程中,首先需要理解“并发”(Concurrency)和“并行”(Parallelism)的区别。“并发”指的是多个任务在同一时间段内交替...

Global site tag (gtag.js) - Google Analytics