文章目录

  • 并发容器
    • BlockingQueue
      • ArrayBlockingQueue
      • LinkedBlockingQueue
      • PriorityBlocking
      • DelayQueue
      • SynchronousQueue
    • BlockingDeque
    • CopyOnWrite
      • CopyOnWriteArrayList
      • CopyOnWriteArraySet
    • ConcurrentLinkedQueue/Deque
    • ConcurrentHashMap
    • ConcurrentSkipListMap/Set
  • 同步工具类
    • AQS实现类
      • CountDownLatch
      • CyclicBarrier
      • Semaphore
      • ReentrantLock
      • ReentrantLockReadWriteLock
      • ThreadPoolExecutor
    • Exchanger
    • Phaser
  • Atomic类
    • AtomicInteger和AtomicLong
    • AtomicBoolean和AtomicReference
    • AtomicStampedReference和AtomicMarkableReference
    • AtomicIntegerFieldUpdater、AtomicLongFieldUpdater和AtomicReferenceFieldUpdater
    • AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray
    • Striped64和LongAdder
  • Lock和Condition
    • 互斥锁
    • 读写锁
    • Condition
    • StampedLock

并发容器

BlockingQueue

ArrayBlockingQueue

LinkedBlockingQueue

PriorityBlocking

DelayQueue

SynchronousQueue

BlockingDeque

CopyOnWrite

CopyOnWriteArrayList

CopyOnWriteArraySet

ConcurrentLinkedQueue/Deque

ConcurrentHashMap

ConcurrentSkipListMap/Set

同步工具类

AQS实现类

AQS是一个用于构建锁、同步器等线程协作工具类的框架,有了AQS后,很多用于线程协作的工具类都可以很方便的被写出来

内部使用了AQS(AbstractQueuedSynchronizer)下的工具类

  1. CountDownLatch(CyclicBarrier->ReentrantLock->AQS)
  2. Semaphore
  3. ThreadPoolExecutor
  4. ReentrantLock
  5. ReentrantLockReadWriteLock


一下介绍各个工具类的使用(源码部分,等看完后,后续补充详细说明

CountDownLatch

作用:计数器

源码

实战

作用一:一个线程等待其他多个线程都执行完毕,再继续自己的工作:

    @Testpublic void countdownlatchTest() throws InterruptedException {final CountDownLatch countDownLatch = new CountDownLatch(5);ExecutorService threadPool = Executors.newFixedThreadPool(5);for (int i = 0; i < 5; i++) {final int finalI = i;threadPool.submit(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(finalI + "开始跑步!");//把倒数值-1,那么之前awiat等待的线程会被唤醒countDownLatch.countDown();}});}System.out.println("等待5个运动员都跑完");//调用await方法的线程开始等待,直到倒数结束countDownLatch.await();System.out.println("所有人都跑完了,比赛结束");}

作用二:多个线程等待某一个线程的信号,同时开始执行

    @Testpublic void countdownlatch2() throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);final CountDownLatch countDownLatch = new CountDownLatch(1);for (int i = 0; i < 5; i++) {final int finalI = i;threadPool.submit(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(finalI + "ready");try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(finalI + "run");}});}Thread.sleep(5000);System.out.println("start run!");countDownLatch.countDown();}

CyclicBarrier

源码


从源码中可以看出,CyclicBarrier利用可重入锁ReentrantLock和Condition
实战

CyclicBarrier构造出一个集结点,当某一个线程执行await()当时候,它就会到这个集结点开始等待,等待达到预定值等待到线程就会统一出发

    public void cyclicBarrierTest() throws InterruptedException {CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {@Overridepublic void run() {System.out.println("集结完毕,准备出发");}});//重复利用for (int i = 0; i < 6; i++) {new Thread(new Task(i, cyclicBarrier)).start();}Thread.sleep(1000 * 100000);}class Task implements Runnable {private int id;private CyclicBarrier cyclicBarrier;public Task(int i, CyclicBarrier cyclicBarrier) {this.id = i;this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {System.out.println("同学" + id + "现在从大门出发");try {Thread.sleep((long) (Math.random() * 1000));System.out.println("同学" + id + "到了自行车驿站,开始等待其他人到达");cyclicBarrier.await();System.out.println("同学" + id + "开始骑车");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}

Semaphore

信号量用来控制需要限制并发访问量的资源

源码


实战

    @Testpublic void semaphoreTest() throws Exception {final Semaphore semaphore = new Semaphore(2);ExecutorService executorService = Executors.newFixedThreadPool(1000);for (int i = 0; i < 1000; i++) {final int finalI = i;executorService.submit(new Runnable() {@Overridepublic void run() {try {semaphore.acquire();Thread.sleep(3000);System.out.println(finalI + "run");} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}System.out.println("--------");}});}Thread.sleep(1000 * 100000);}

ReentrantLock

源码


实战
未使用锁情况:出现线程安全问题

    @Testpublic void ReentrantLockTest() {ReentrantLock lock = new ReentrantLock();CountDownLatch countDownLatch = new CountDownLatch(1);//模拟10个并发for (int i = 0; i < 10; i++) {final int n = i;new Thread(new Runnable() {@Overridepublic void run() {System.out.println(n + " 线程变成运行状态,等待命令");try {countDownLatch.await();/*** tryLock的方法就是试一下,如果能得到锁,就返回真,如果当时得不到,马上就返回假,绝不等。tryLock(时间)的用法就是 在规定的时间内设法得到锁。如果在规定的时间内最终不能得到锁,就返回假。* tryLock()方法只有在成功获取了锁的情况下才会返回true,如果别的线程当前正持有锁,则会立即返回false*/
//                        while (!lock.tryLock()) ;compute(n);} catch (InterruptedException e) {e.printStackTrace();} finally {//                        lock.unlock();}}}).start();}try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程创建完毕,准备计数!");countDownLatch.countDown();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("计数结果:" + k);}private void compute(int n) {for (int j = 0; j < 10000; j++) {if (n % 2 == 0) {k--;} else {k++;}}}

采用锁情况:返回结果为0,没有线程安全问题

    @Testpublic void ReentrantLockTest() {ReentrantLock lock = new ReentrantLock();CountDownLatch countDownLatch = new CountDownLatch(1);//模拟10个并发for (int i = 0; i < 10; i++) {final int n = i;new Thread(new Runnable() {@Overridepublic void run() {System.out.println(n + " 线程变成运行状态,等待命令");try {countDownLatch.await();/*** tryLock的方法就是试一下,如果能得到锁,就返回真,如果当时得不到,马上就返回假,绝不等。tryLock(时间)的用法就是 在规定的时间内设法得到锁。如果在规定的时间内最终不能得到锁,就返回假。* tryLock()方法只有在成功获取了锁的情况下才会返回true,如果别的线程当前正持有锁,则会立即返回false*/while (!lock.tryLock()) ;compute(n);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}).start();}try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程创建完毕,准备计数!");countDownLatch.countDown();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("计数结果:" + k);}private void compute(int n) {for (int j = 0; j < 10000; j++) {if (n % 2 == 0) {k--;} else {k++;}}}

ReentrantLockReadWriteLock

多线程情况下:读-写互斥、写-读互斥、写-写互斥、读-读共享
使用场景:
对于数据比较敏感的场景,
读锁:在读取数据时是不能出现多次读取不一致的情况的,这点有点像可重复读和幻读,
写锁:写数据时,又不能同时读取数据

 参考博客:https://www.cnblogs.com/zxporz/p/10874853.html

源码

实战

   private final Map<String, Integer> map = new TreeMap<>();private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();private final Lock readLock = lock.readLock();private final Lock writeLock = lock.writeLock();public Integer get(String key) {readLock.lock();try {return map.get(key);} finally {readLock.unlock();}}public Set<String> allKeys() {readLock.lock();try {return map.keySet();} finally {readLock.unlock();}}public Integer put(String key, Integer value) {writeLock.lock();try {return map.put(key, value);} finally {writeLock.unlock();}}public void clear() {writeLock.lock();try {map.clear();} finally {writeLock.unlock();}}

ThreadPoolExecutor

用来构建线程池

源码


实战

    @Testpublic void threadpoolExcutorTest() throws ExecutionException, InterruptedException {ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),new ThreadPoolExecutor.DiscardOldestPolicy());/*** 模拟20个并发,3个核心线程数、最大线程数5个,阻塞队列容量为10,* 此时处理流程?** 取决于用何种拒绝策略* 1.如果用到是默认拒绝策略:AbortPolicy 此时程序直接抛出RejectedExecutionException到RuntimeException异常,* 为unchecked异常,如果不手动捕获程序就会异常退出* java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@64a294a6* rejected from java.util.concurrent.ThreadPoolExecutor@7e0b37bc[Running, pool size = 5, active threads = 5, queued tasks = 10, completed tasks = 0]* 2.如果是DiscardPolicy:新任务提交后直接被丢弃了,也不会给你任何到通知* 0-thread run* 1-thread run* 2-thread run* 3-thread run* 4-thread run* 5-thread run* 6-thread run* 7-thread run* 8-thread run* 9-thread run* 10-thread run* 11-thread run* 12-thread run* 13-thread run* 14-thread run* 3.如果是DiscardOldestPolicy,丢弃任务队列中到头节点,通常是存活时间最长到任务,存在数据丢失风险* 0-thread run* 1-thread run* 2-thread run* 4.如果是CallerRunsPolicy,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交给提交任务到线程去执行* 0-thread run* 1-thread run* 2-thread run* 3-thread run* 4-thread run* 5-thread run* 6-thread run* 7-thread run* 8-thread run* 9-thread run* 10-thread run* 11-thread run* 12-thread run* 13-thread run* 14-thread run* 15-thread run* 16-thread run* 17-thread run* 18-thread run* 19-thread run*/ArrayList<Future> futureList = new ArrayList<>(20);for (int i = 0; i < 20; i++){final int finalI = i;Future<String> future = threadPoolExecutor.submit(new Callable<String>() {@Overridepublic String call() throws Exception {Thread.sleep(1000);return finalI + "-thread run";}});futureList.add(future);}for (int i = 0; i < 20; i++){try {System.out.println(futureList.get(i).get(1000, TimeUnit.SECONDS));} catch (TimeoutException e) {e.printStackTrace();}}try {Thread.sleep(1000 * 10000);} catch (InterruptedException e) {e.printStackTrace();}}

Exchanger

Phaser

Atomic类

AtomicInteger和AtomicLong

AtomicBoolean和AtomicReference

AtomicStampedReference和AtomicMarkableReference

AtomicIntegerFieldUpdater、AtomicLongFieldUpdater和AtomicReferenceFieldUpdater

AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray

Striped64和LongAdder

Lock和Condition

互斥锁

读写锁

Condition

StampedLock

【待完成】并发包下常用到线程工具类汇总相关推荐

  1. Linux下常用日志分析工具

    Linux下常用日志分析工具 Logcheck简介 对于拥有大量账户.系统繁忙的Linux系统而言,其日志文件是极其庞大的,很多没有用的信息会将值得注意的信息淹没,给用户分析日志带来了很大的不便.现在 ...

  2. Hutool Java常用工具类汇总

    简介 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以"甜甜的". Hu ...

  3. java 文件拷贝保留原来的属性_Java常用属性拷贝工具类使用总结

    开头聊几句 1.网上很多的技术文章和资料是有问题的,要学会辨证的看待,不能随便就拿来用,起码要自己验证一下 2.关注当下,关注此刻,如果你真正阅读本篇文章,请花几分钟时间的注意力阅读,相信你会有收获的 ...

  4. java工具类怎么写_常用的Java工具类——十六种

    常用的Java工具类--十六种 在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类.以下工具类.方法按使用流行度排名,参考数据来源于Github上随机选 ...

  5. 线程工具类(根据电脑逻辑处理器个数控制同时运行的线程个数)

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  6. 常用Apache Commons工具类备忘

    常用Apache Commons工具类 ----------------------------------------------------------------- 例如:commons.lan ...

  7. java中常用的日期工具类

    java中常用的日期工具类 日期相关的类: package net.yto.ofclacct.core.util;import java.text.ParseException; import jav ...

  8. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  9. Android常用的工具类汇总(方便日后使用)

    平时进行android开发时候,可能需要使用各种各样的工具类,每次总要去上网搜索,费时费力,因此特此将其整理发出来,小伙伴可自行收藏. 1.LogUtils工具类 /*** 控制Log开关的工具类*/ ...

最新文章

  1. 基于USEARCH或QIIME绘制Alpha多样性稀释曲线(rarefraction curve)
  2. linux tomcat 安装教程,关于Linux下配置安装Tomcat8的步骤
  3. 南京大学「自然指数」超越清华北大,位列全国高校第一、世界第七,突显学术实力...
  4. python装饰器-python装饰器简介---这一篇也许就够了(推荐)
  5. wordpress中PHP运行错最有效解决办法Fatal error: Out of memory (allocated 6029312)(转)
  6. 【转:SAP PS】 创建项目Project
  7. ruby之添加当前文件路径到$LOAD_PATH
  8. 记一次 .NET医疗布草API程序 内存暴涨分析
  9. Magicodes.IE之导入学生数据教程
  10. net发布的dll方法和类显示注释信息(字段说明信息)[图解]
  11. ESP8285 ESP-AT编译流程和操作步骤
  12. Mac SnailSVN不显示状态图标
  13. 敏捷开发中的文档怎么写
  14. word:回车替换成空格
  15. 无线Beacon帧解析
  16. 阴阳师ios和android,《阴阳师》App Store表现优异,安卓苹果惊喜同服
  17. C++ 标准库的双向链表
  18. 苹果录屏功能没有声音_手机录屏没有声音如何处理?可以从这三个方面入手看看...
  19. 论文那些事—ZOO: Zeroth Order Optimization Based Black-box Attacks
  20. JT/T808消息体转义

热门文章

  1. controller中执行main方法报错NoClassDefFoundError: javax/servlet/http/HttpServletResponse
  2. CoreAnimation编程指南(六)动画
  3. 碧雪情天服务器地址源如何修改,稀有游戏《碧雪情天online》网络版王者归来一键服务端+客户端 支持转生系统和新图...
  4. 现代软件工程 作业 原型设计
  5. python 硬件模拟_如何编写一个硬件模拟器?
  6. 逻辑代数01律的理解_零基础学习计算机原理:布尔逻辑和逻辑门
  7. python max取下标_Python 变量类型总结
  8. python语言例子_【Python】SimPy的使用示例-Go语言中文社区
  9. linux std::queue 怎么释放内存_电脑卡慢怎么办?一个小工具帮你轻松释放内存,瞬间提升电脑性能...
  10. 【LeetCode笔记】399. 除法求值(Java、图)