Java中几种并发容器的使用

简介: Java中几种并发容器的使用

文章目录

一、并发容器

CountDownLatch

CountDownLatch它可以实现类似计数器的功能,当前线程需要等待其他任务执行完成才开始执行。

   /**

    * 构造函数初始化计数的数量,需要等待执行的任务个数

    */

   public CountDownLatch(int count) {

       if (count < 0) throw new IllegalArgumentException("count < 0");

       this.sync = new Sync(count);

   }

   /**

    * 任务执行完毕之后,减去1,当等待任务为0时,唤醒其他线程。

    */

 

public void countDown() {

       sync.releaseShared(1);

   }

    /**

    * 当前线程等到线程的计数器为0时候开始继续执行。

    */

public void await() throws InterruptedException {

       sync.acquireSharedInterruptibly(1);

   }

示例

public class CountDownLatchDemo {

   public static void main(String[] args) throws InterruptedException {

       final CountDownLatch latch = new CountDownLatch(1);

       new Thread(()->{

           System.out.println(Thread.currentThread().getName()+"执行开始....");

           try {

               Thread.sleep(3);

           } catch (InterruptedException e) {

               throw new RuntimeException(e);

           }

           System.out.println(Thread.currentThread().getName()+"执行结束....");

           latch.countDown();

       },"t1").start();

       System.out.println("等待t1线程执行完毕...");

       latch.await();

       System.out.println("t1线程已经执行完毕");

       System.out.println("继续执行主线程");

   }

}

注释掉latch.await(),输出

等待t1线程执行完毕...

t1线程已经执行完毕

继续执行主线程

t1执行开始....

t1执行结束....

加上latch.await(),输出

等待t1线程执行完毕...

t1执行开始....

t1执行结束....

t1线程已经执行完毕

继续执行主线程

CyclicBarrier (回环栅栏)

CyclicBarrier它的作用就是会让所有线程都等待完成后才会继续下一步行

动。

构造器

/**

CyclicBarrier初始化时规定一个数目,

然后计算调用了CyclicBarrier.await()进入等待的线程数。

当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。

*/

  public CyclicBarrier(int parties) {

       this(parties, null);

   }

CyclicBarrier 中最重要的方法就是await 方法:

/**

用来挂起当前线程,直至所有线程都到达barrier 状态再同时执行后续任

务;

*/

public int await() throws InterruptedException, BrokenBarrierException {

       try {

           return dowait(false, 0L);

       } catch (TimeoutException toe) {

           throw new Error(toe); // cannot happen

       }

   }

示例

public class CyclicBarrierDemo {

   public static void main(String[] args) {

       //模拟5个人聚会,先后时间到达,人员到齐之后才可以进行活动

       int N =5;

       CyclicBarrier barrier = new CyclicBarrier(N);

       for(int i=1;i<=N;i++) {

           new Person("person" + i, barrier).start();

       }

   }

   static class Person extends Thread {

       private CyclicBarrier cyclicBarrier;

       public Person(String personname,CyclicBarrier cyclicBarrier) {

           super(personname);

           this.cyclicBarrier = cyclicBarrier;

       }

       @Override

       public void run() {

           try {

               Thread.sleep(3);

               System.out.println("人员" + Thread.currentThread().getName() + " 到,等待其他人到场");

               cyclicBarrier.await();

           } catch (InterruptedException e) {

               e.printStackTrace();

           } catch (BrokenBarrierException e) {

               e.printStackTrace();

           }

           System.out.println("所有人到齐,可以进行其他活动");

       }

   }

}

人员person1 到,等待其他人到场

人员person3 到,等待其他人到场

人员person4 到,等待其他人到场

人员person2 到,等待其他人到场

人员person5 到,等待其他人到场

所有人到齐,可以进行其他活动

所有人到齐,可以进行其他活动

所有人到齐,可以进行其他活动

所有人到齐,可以进行其他活动

所有人到齐,可以进行其他活动

Semaphore (信号量)

Semaphore 可以控制同时访问的线程个数,通过acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

示例

public class SemaphoreDemo {

   public static void main(String[] args) {

       int N = 5; //购票场景,5个人需要购买票,人工窗口只有2个

       Semaphore semaphore = new Semaphore(2); //人工窗口

       for(int i=1;i<=N;i++)

           new BuyTicketor(i,semaphore).start();

   }

   static class BuyTicketor extends Thread{

       private int num;

       private Semaphore semaphore;

       public BuyTicketor(int num,Semaphore semaphore){

           this.num = num;

           this.semaphore = semaphore;

       }

       @Override

       public void run() {

           try {

               semaphore.acquire();

               System.out.println("购买者"+this.num+"购买票中...");

               Thread.sleep(3);

               System.out.println("购买者"+this.num+"购买完成...");

               semaphore.release();

           } catch (InterruptedException e) {

               e.printStackTrace();

           }

       }

   }

}

输出

购买者1购买票中...

购买者2购买票中...

购买者2购买完成...

购买者1购买完成...

购买者3购买票中...

购买者4购买票中...

购买者4购买完成...

购买者3购买完成...

购买者5购买票中...

购买者5购买完成...


相关文章
|
2月前
|
Java 虚拟化 容器
(Java)Java里JFrame窗体的基本操作(容器布局篇-1)
容器 容器,我的理解是可以包容其他东西的玩意。它可以是一个盒子,可以是一个虚拟化的物品,可只要能包裹住其他存在质体的东西,那么都可以称作是容器。例如:JPanel组件和JScollPane组件两者都是容器也是组件。 既然有容器,那么容器中的布局就必不可少了。不然不规矩的摆放物品,人类看不习惯,我也看不习惯 ???? 本篇内容,将说明java JFrame窗体里容器中几类布局。 说明:所有在JFrame窗体里的容器布局都会使用setLayout()方法,采用的布局参数都将放进这个方法里 绝对布局 调用窗体容器
100 1
|
2月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
75 4
|
2月前
|
缓存 安全 Java
如何理解Java中的并发?
Java并发指多任务交替执行,提升资源利用率与响应速度。通过线程实现,涉及线程安全、可见性、原子性等问题,需用synchronized、volatile、线程池及并发工具类解决,是高并发系统开发的关键基础。(238字)
210 4
|
5月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
362 83
|
5月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
341 83
|
8月前
|
消息中间件 算法 安全
JUC并发—1.Java集合包底层源码剖析
本文主要对JDK中的集合包源码进行了剖析。
|
7月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
259 0
|
5月前
|
SQL 缓存 安全
深度理解 Java 内存模型:从并发基石到实践应用
本文深入解析 Java 内存模型(JMM),涵盖其在并发编程中的核心作用与实践应用。内容包括 JMM 解决的可见性、原子性和有序性问题,线程与内存的交互机制,volatile、synchronized 和 happens-before 等关键机制的使用,以及在单例模式、线程通信等场景中的实战案例。同时,还介绍了常见并发 Bug 的排查与解决方案,帮助开发者写出高效、线程安全的 Java 程序。
244 0
|
6月前
|
Java 物联网 数据处理
Java Solon v3.2.0 史上最强性能优化版本发布 并发能力提升 700% 内存占用节省 50%
Java Solon v3.2.0 是一款性能卓越的后端开发框架,新版本并发性能提升700%,内存占用节省50%。本文将从核心特性(如事件驱动模型与内存优化)、技术方案示例(Web应用搭建与数据库集成)到实际应用案例(电商平台与物联网平台)全面解析其优势与使用方法。通过简单代码示例和真实场景展示,帮助开发者快速掌握并应用于项目中,大幅提升系统性能与资源利用率。
191 6
Java Solon v3.2.0 史上最强性能优化版本发布 并发能力提升 700% 内存占用节省 50%

热门文章

最新文章