Java并发编程 - AQS 之 CyclicBarrier(二)

简介: Java并发编程 - AQS 之 CyclicBarrier(二)

案例二


package com.mmall.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Slf4j
public class CyclicBarrierExample2 {
    private static CyclicBarrier barrier = new CyclicBarrier(5);
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int threadNum = i;
            Thread.sleep(1000);
            executor.execute(() -> {
                try {
                    race(threadNum);
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        executor.shutdown();
    }
    private static void race(int threadNum) throws Exception {
        Thread.sleep(1000);
        log.info("{} is ready", threadNum);
        try {
            barrier.await(2000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        log.info("{} continue", threadNum);
    }
}
// 输出
21:43:03.378 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 0 is ready
21:43:04.376 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 1 is ready
21:43:05.376 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 2 is ready
21:43:05.382 [pool-1-thread-1] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:05.382 [pool-1-thread-2] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:05.382 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 0 continue
21:43:05.382 [pool-1-thread-3] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:05.382 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 1 continue
21:43:05.382 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 2 continue
21:43:06.377 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 3 is ready
21:43:06.377 [pool-1-thread-4] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:06.377 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 3 continue
21:43:07.377 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 4 is ready
21:43:07.377 [pool-1-thread-3] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:07.377 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 4 continue
21:43:08.378 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 5 is ready
21:43:08.378 [pool-1-thread-4] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:08.378 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 5 continue
21:43:09.378 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 6 is ready
21:43:09.378 [pool-1-thread-3] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:09.378 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 6 continue
21:43:10.379 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 7 is ready
21:43:10.379 [pool-1-thread-4] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:10.379 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 7 continue
21:43:11.380 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 8 is ready
21:43:11.380 [pool-1-thread-3] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:11.380 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 8 continue
21:43:12.380 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 9 is ready
21:43:12.380 [pool-1-thread-4] WARN  c.m.concurrency.example.aqs.test9 - Exception
21:43:12.380 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 9 continue
Process finished with exit code 0

分析 await(timeout,TimeUnit) 方法


在 CyclicBarrier 上进行限时的阻塞等待,直到发生以下情形之一。

在 CyclicBarrier 上等待的线程数量达到 parties,则所有线程被释放,继续执行。

当前线程被中断,则抛出 InterruptedException 异常,并停止等待,继续执行。

当前线程等待超时,则抛出 TimeoutException 异常,并停止等待,继续执行。

其他等待的线程被中断,则当前线程抛出 BrokenBarrierException 异常,并停止等待,继续执行。

其他等待的线程超时,则当前线程抛出 BrokenBarrierException 异常,并停止等待,继续执行。

其他线程调用 CyclicBarrier.reset() 方法,则当前线程抛出 BrokenBarrierException 异常,并停止等待,继续执行。



案例三

package com.mmall.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class CyclicBarrierExample3 {
    private static CyclicBarrier barrier = new CyclicBarrier(5, () -> {
        log.info("callback is running");
    });
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int threadNum = i;
            Thread.sleep(1000);
            executor.execute(() -> {
                try {
                    race(threadNum);
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        executor.shutdown();
    }
    private static void race(int threadNum) throws Exception {
        Thread.sleep(1000);
        log.info("{} is ready", threadNum);
        barrier.await();
        log.info("{} continue", threadNum);
    }
}
// 输出
21:47:26.683 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 0 is ready
21:47:27.682 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 1 is ready
21:47:28.684 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 2 is ready
21:47:29.683 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 3 is ready
21:47:30.683 [pool-1-thread-5] INFO  c.m.concurrency.example.aqs.test9 - 4 is ready
21:47:30.683 [pool-1-thread-5] INFO  c.m.concurrency.example.aqs.test9 - callback is running
21:47:30.683 [pool-1-thread-5] INFO  c.m.concurrency.example.aqs.test9 - 4 continue
21:47:30.683 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 0 continue
21:47:30.683 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 1 continue
21:47:30.683 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 2 continue
21:47:30.683 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 3 continue
21:47:31.684 [pool-1-thread-6] INFO  c.m.concurrency.example.aqs.test9 - 5 is ready
21:47:32.684 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 6 is ready
21:47:33.685 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 7 is ready
21:47:34.685 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 8 is ready
21:47:35.685 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 9 is ready
21:47:35.685 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - callback is running
21:47:35.685 [pool-1-thread-1] INFO  c.m.concurrency.example.aqs.test9 - 9 continue
21:47:35.686 [pool-1-thread-6] INFO  c.m.concurrency.example.aqs.test9 - 5 continue
21:47:35.686 [pool-1-thread-4] INFO  c.m.concurrency.example.aqs.test9 - 6 continue
21:47:35.686 [pool-1-thread-3] INFO  c.m.concurrency.example.aqs.test9 - 7 continue
21:47:35.686 [pool-1-thread-2] INFO  c.m.concurrency.example.aqs.test9 - 8 continue
Process finished with exit code 0
  • 在案例一的基础上,无非新增了一个回调函数功能:在线程达到屏障的时候,优先执行该回调函数先。
目录
打赏
0
0
0
0
37
分享
相关文章
|
22天前
|
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
前言 主播觉得,AQS的原理,就是通过这2个队列的协助,实现核心功能,同步队列(CLH队列)和条件队列(Condition队列)。 同步队列(CLH队列) 作用:管理需要获...
66 18
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
【Java并发】【AQS】适合初学者体质的AQS入门
AQS这是灰常重要的哈,很多JUC下的框架的核心,那都是我们的AQS,所以这里,我们直接开始先研究AQS。 那说到研究AQS,那我们应该,使用开始说起🤓 入门 什么是AQS? AQS(Abst
71 8
【Java并发】【AQS】适合初学者体质的AQS入门
k8s的出现解决了java并发编程胡问题了
Kubernetes通过提供自动化管理、资源管理、服务发现和负载均衡、持续交付等功能,有效地解决了Java并发编程中的许多复杂问题。它不仅简化了线程管理和资源共享,还提供了强大的负载均衡和故障恢复机制,确保应用程序在高并发环境下的高效运行和稳定性。通过合理配置和使用Kubernetes,开发者可以显著提高Java应用程序的性能和可靠性。
78 31
注解的艺术:Java编程的高级定制
注解是Java编程中的高级特性,通过内置注解、自定义注解及注解处理器,可以实现代码的高度定制和扩展。通过理解和掌握注解的使用方法,开发者可以提高代码的可读性、可维护性和开发效率。在实际应用中,注解广泛用于框架开发、代码生成和配置管理等方面,展示了其强大的功能和灵活性。
71 25
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
以上内容是一个简单的实现在Java后端中通过DockerClient操作Docker生成python环境并执行代码,最后销毁的案例全过程,也是实现一个简单的在线编程后端API的完整流程,你可以在此基础上添加额外的辅助功能,比如上传文件、编辑文件、查阅文件、自定义安装等功能。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
课时6:Java编程起步
课时6:Java编程起步,主讲人李兴华。课程摘要:介绍Java编程的第一个程序“Hello World”,讲解如何使用记事本或EditPlus编写、保存和编译Java源代码(*.java文件),并解释类定义、主方法(public static void main)及屏幕打印(System.out.println)。强调类名与文件名一致的重要性,以及Java程序的编译和执行过程。通过实例演示,帮助初学者掌握Java编程的基本步骤和常见问题。
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
141 5
Java 并发编程——volatile 关键字解析
|
10月前
|
关于《Java并发编程之线程池十八问》的补充内容
【6月更文挑战第6天】关于《Java并发编程之线程池十八问》的补充内容
80 5
Java中的并发编程:理解并应用线程池
在Java的并发编程中,线程池是提高应用程序性能的关键工具。本文将深入探讨如何有效利用线程池来管理资源、提升效率和简化代码结构。我们将从基础概念出发,逐步介绍线程池的配置、使用场景以及最佳实践,帮助开发者更好地掌握并发编程的核心技巧。
Java中的并发编程:深入理解线程池
在Java的并发编程中,线程池是管理资源和任务执行的核心。本文将揭示线程池的内部机制,探讨如何高效利用这一工具来优化程序的性能与响应速度。通过具体案例分析,我们将学习如何根据不同的应用场景选择合适的线程池类型及其参数配置,以及如何避免常见的并发陷阱。
91 1