Java并发工具辅助类代码实例

网友投稿 217 2022-12-09


Java并发工具辅助类代码实例

java中的并发工具类

一:等待多线程完成的CountDownLatch

CountDownLatch允许一个或多个线程等待其他线程完成操作。

package com.fuzhulei;

import java.util.concurrent.*;

/**

* 减法计数器,主要是countDown(计数器1) 和 await(阻塞)方法,只有当计数器减为0的时候,当前线程才可以往下继续执行。

* 主要用于允许一个或多个线程等待其他线程完成操作

* @author Huxudong

* @createTime 2020-04-05 00:04:36

**/

public class CountDownDemo {

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

/** 使用其构造函数,创建一个数值为6的计数器 */

CountDownLatch countDownLatch = new CountDownLatch(6);

/** 自定义线程池使用 */

ExecutorService pool = new ThreadPoolExecutor(

6, // 核心线程池大小

9, // 最大线程池的大小(根据是IO密集型,还是CPU密集型来确定大小)

3L, // 超时等待时间

TimeUnit.SECONDS, // 时间的单位

new LinkedBlockingQueue<>(5), // 阻塞队列是哪一种

Executors.defaultThreadFactory(), // 默认线程创建工厂

new ThreadPoolExecutor.AbortPolicy() // 四大拒绝策略,选择一种

);

try{

for (int i = 0; i < 6; i++) {

/** 这个线程的提交,没有返回值的任务 */

pool.execute(()->{

countDownLatch.countDown();

System.out.println(Thread.currentThread().getName()+"执行一次减法");

});

}

} catch(Exception e) {

e.printStackTrace();

} finally {

/** 关闭线程池 */

pool.shutdown();

}

countDownLatch.await();

System.out.println("执行完成了");

R03;

}

}

正确执行结果:

但是如果我们设置计数器的容量大于6的话(相对于我的程序而言),就会被阻塞在那里

会发现执行完成了 没有被打印出来,而且程序一直没有停止,这个时候就是因为计数器没有归0,所以当前线程被阻塞,不能向下面继续进行。

二:同步屏障CyclicBarrier

CyclicBarrier的翻译大致就是可循环的屏障。它主要的作用就是让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一份线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。

package com.fuzhulei;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

/**

* CyclicBarrier是一个加法计数器,即同步屏障,可循环的屏障,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障,达到了一开始初始化的屏障的数值,

* 屏障才可以打开门,所有被拦截的线程才可以继续工作,主要是通过调用await方法来实现的

* @author Huxudong

* @createTime 2020-04-04 22:53:50

**/

public class CyclicBarrierDemo {

public static void main(String[] args) {

CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

new Thread(()->{

try {

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println("线程A已经到达屏障");

},"A").start();

new Thread(()->{

try {

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println("线程B已经到达屏障");

},"B").start();

new Thread(()->{

try {

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println("线程C已经到达屏障");

},"C").start();

}

}

执行的结果如下:

但是如果把定义的容量大于3(相对于我的程序而言),就会发现什么都不会输出了,看截图

并且程序一直还没有停止,这就是屏障起到了作用,因为屏障要求至少需要4个(假设),但是此时只有三个线程到达,所以不满足,屏障就一直阻拦不放路,那么所有的线程也就被阻塞不能向下面继续运行,除非知道第四个过来,满足条件才会运行。

三:控制并发线程数的Semaphore

用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用公用的资源。

package com.fuzhulei;

import java.util.concurrent.*;

/**

* 用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用公用的资源

* @author Huxudong

* @createTime 2020-04-04 23:45:29

**/

public class SemaphoreDemo {

public static void main(String[] args) {

Semaphore semaphore = new Semaphore(5);

ExecutorService pool = new ThreadPoolExecutor(

10,

20,

3L,

TimeUnit.SECONDS,

new LinkedBlockingQueue<>(20),

Executors.defaultThreadFactory(),

new ThreadPoolExecutor.AbortPolicy());

try{

for (int i = 0; i < 60vnHPZzcHy; i++) {

pool.execute(() ->{

try {

semaphore.acquire();

System.out.println(Thread.currentThread().getName()+"限流成功");

semaphore.release();

} catch (InterruptedException e) {

e.printStackTrace();

}

});

}

} catch(Exception e) {

e.printStackTrace();

} finally {

pool.shutdown();

}

}

}

执行的结果如下:

例如:数据库资源,假如需要读取几十万个数据的文件,因为都是IO密集型任务,所以开了2倍的处理器+1个线程数(IO密集型,所以线程可以多一些,让cpu忙起来,因为IO操作的时候,很少操作Cpu)

但是如果读到内存后,还需要存储到数据库中,但是数据库连接我们设置的加入就10个,所以我们必须控制只有10个线程可以同时访问数据库连接保存数据,否则会报错无法连接数据库异常。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java学习笔记:基本输入、输出数据操作实例分析
下一篇:Spring注解驱动之AOP功能测试
相关文章

 发表评论

暂时没有评论,来抢沙发吧~