
juc
文章平均质量分 83
多线程学习笔记
weihubeats
开源框架Tlog贡献者,技术大多都源于生产实践,乐于分享.公众号:小奏技术
展开
-
如何实现一个内存安全的队列
而整个逻辑里面的核心逻辑就是调用 Instrumentation 类型的 getObjectSize 方法获得当前放入对象的一个 size,并判断当前已经使用的值加上这个 size 之后,是否大于了我们设置的最大值。思路扩展一下,比如我们有的项目里面用 Map 来做本地缓存,就会放很多元素进去,也会有 OOM 的风险,那么通过前面说的思路,是不是就找到了一个问题的解决方案?看方法名称你也知道了,get 这个 object 的 size,这个 object 就是方法的入参,也就是要放入到队列里面的元素。转载 2022-09-13 08:14:22 · 558 阅读 · 1 评论 -
高性能并发队列Disruptor
寻找更高性能的并发队列队列的底层一般分成三种:数组、链表和堆。其中,堆一般情况下是为了实现带有优先级特性的队列,暂且不考虑从数组和链表两种数据结构来看,基于数组线程安全的队列,比较典型的是ArrayBlockingQueue,它主要通过加锁的方式来保证线程安全;基于链表的线程安全队列分成LinkedBlockingQueue和ConcurrentLinkedQueue两大类,前者也通过锁的方式来实现线程安全,而后者以及上面表格中的LinkedTransferQueue都是通过原子变量compare and原创 2022-06-13 23:02:01 · 426 阅读 · 0 评论 -
面试官:ThreadLocal解决线程之间值传递, InheritableThreadLocal解决父子线程值传递,线程池值如何传递呢
线程、父子线程、线程池我们知道线程之间的值传递使用JDK自带的ThreadLocal即可解决,如果遇到需要父子线程值传递的场景也可以使用JDK提供的InheritableThreadLocal,但更多的业务场景实际是需要把任务提交给线程池时的ThreadLocal值传递到任务执行时关于InheritableThreadLocal详细介绍说明请参考之前博文https://weihubeats.blog.youkuaiyun.com/article/details/122391429InheritableThr原创 2022-03-06 15:00:21 · 954 阅读 · 0 评论 -
看到同事还在乱定义线程池参数,我直接封装一个线程池建造工具类
文章目录背景任务异常log的获取线程池线程数不知道如何设置需要解决线程池的线程数设置线程池名字编码实现ThreadFactoryImplThreadPoolUtilThreadPoolBuilder使用总结背景相信不少工作中的小伙伴都会使用线程池,但是线程池的定义使用是个一个比较复杂的过程,因为单是线程池构造函数就有7个之多,并且每个参数的定义也不是简单的基本数据结构直接传入就好了所以一些没有经验的小伙伴就使用jdk提供的默认的线程池建造工具类ExecutorsExecutors 也确实提供了一原创 2022-01-15 12:03:39 · 1074 阅读 · 0 评论 -
你是否遇到ThreadLocal父子线程传递值丢失?了解下InheritableThreadLocal?
在了解InheritableThreadLocal先确定你已经了解了ThreadLocal我们知道ThreadLocal可以实现线程之间值的传递,但是如果是父子线程呢?我们来看一个简单的例子 private static final ThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); private static final ThreadLocal<Stri.原创 2022-01-09 11:31:02 · 724 阅读 · 0 评论 -
多线程异步编程之Java8 CompletableFuture详解(保姆级教程)
文章目录背景类结构学习使用创建异步任务`supplyAsync``runAsync`异步回调`thenApply``thenAccept``thenRun``exceptionally``whenComplete``handle`联合处理双CompletableFuture联合处理`thenCombine``thenAcceptBoth``runAfterBoth``applyToEither``acceptEither``runAfterEither``thenCompose`多CompletableFu原创 2021-08-30 07:30:17 · 5854 阅读 · 2 评论 -
只会原子类AtomicLong不懂Longadder?我怀疑你多线程计数没我快
文章目录背景性能比对源码分析核心属性`Celll`类add参考背景在看本篇文章,希望你已经对多线程和原子类有了一定的了解。说说我们在多线程对一些变量做自增同时要保证线程安全,我们最容易使用高性能的原子类来处理,因为他们是采用cas保证线程安全的,一般情况下比重量级加锁性能更佳,所以能用原子类的地方我们尽力不使用加锁。但是有没有比原子类更快线程安全的累加计数器呢?答案是有的,那就jdk1.8新引入juc包中的Longadder性能比对我们先来基于Longadder和AtomicLong性能作一个比较原创 2021-08-21 21:28:40 · 271 阅读 · 0 评论 -
ThreadLocal真的存在内存泄漏吗?来这里探讨真相吧
文章目录背景ThreadLocal应用场景代码演示自我设计jdk中的设计内存泄漏问题探讨再谈`ThreadLocalMap`弱引用问题总结后续背景一直以项目中就经常使用ThreadLocal,但是对他的原理总是迷迷糊糊,每次想要了解,就打开网上看看别人的博客,发现写的都大同小异,然后又不太清楚,导致自己对ThreadLocal原理总是一知半解,今天总算有空来自己研究研究ThreadLocal,今天就带领大家来探讨久违的真相ThreadLocal应用场景这里先介绍下ThreadLocal的应用场景。原创 2021-08-15 16:30:31 · 603 阅读 · 0 评论 -
伪共享都不知道如何提高并发编程效率?
文章目录背景CPU缓存架构缓存行如何避免伪共享背景在学习一些比较高性能的并发类,比如Disruptor、LongAdder之前,我们要先打一个基础,就是了解什么是伪共享CPU缓存架构伪共享是如何产生的呢?我们还是要从硬件级别的CPU缓存架构谈起CPU 是计算机的心脏,所有运算和程序最终都要由它来执行。然而CPU的执行速度又是非常快的,如果仅仅让CPU去从磁盘读取指令,那么CPU就会长时间不运行在等待磁盘加载指令,所以为了高效的让CPU工作,我们就需要在磁盘与CPU之间添加一些缓存。所以整个CPU缓原创 2021-07-26 20:26:47 · 176 阅读 · 0 评论 -
比读写锁(ReadWriteLock)更快的锁(StampedLock)
区别ReadWriteLock 支持两种模式:读锁写锁。而 StampedLock 支持三种模式:写锁悲观读锁(等价于ReadWriteLock 读锁)乐观读这里可以看到StampedLock在命名上没有Reentrant前缀,所以StampedLock是不可重入锁可以看到 StampedLock 也是和ReadWriteLock类似有读锁和写锁,也是运行多个线程同时获取悲观读锁,但是只运行一个线程获取写锁,写锁和悲观读锁是互斥的。不过有一点不同的是StampedLock 里的原创 2021-07-19 20:40:08 · 437 阅读 · 0 评论 -
Java8 并行流(parallelStream)原理分析及线程池线数设置
我们都知道在java 使用strem流做多线程处理是非常方便的。list.parallelStream().forEach(s -> { // 业务处理 });但是parallelStream是如何实现多线程处理的呢?其实看源码我们会发现parallelStream是使用线程池ForkJoin来调度的,这里我们可以看源码看到由于我们使用的 forEach,所以直接看类ForEachOps即可.当然其他方法比如reduce等会有不同的实现类,总的实现类是如原创 2021-05-02 23:17:37 · 24839 阅读 · 2 评论 -
synchronized 我理解的到底有多深
synchronize 作用synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。人话解释就是解决多线程并发访问冲突问题。保证原子性,可见性,有序性(单线程执行依然会有指令重排序,但是由于是单线程执行,所以还是能保证有序性)synchronized锁的谁首先需要说明的是Java 中任何一个对象都可以作为synchronized 锁。具体锁分如下几种情况普通同步方法锁是当前实例对象静态同步方法,锁是当前类的class对原创 2021-03-27 21:35:06 · 281 阅读 · 0 评论 -
ExecutorService 和 ExecutorCompletionService 使用区别及ExecutorCompletionService的应用场景
假设我们有这样一个需求,现在有A系统,部署了三个节点。我们需要获取A系统的一个接口数据,需要最快返回返回结果,而不是至少单纯调用某个节点,在某个节点调用不通再去掉用另外一个节点。这种需求如何实现呢?这就是类似Dubbo 中的 Forking Cluster。其实实现起来也比较简单,我们只需要使用一个线程池同时去调用三个节点,哪个节点获取到了任务就直接返回,并停止其他任务即可。而CompletionService 就是可以这样处理,下面我们对CompletionService 作一个简单的了解吧Compl原创 2021-03-21 12:59:17 · 734 阅读 · 0 评论 -
ReentrantReadWriteLock详解
ReentrantReadWriteLock 是读写锁,和ReentrantLock会有所不同,对于读多写少的场景使用ReentrantReadWriteLock 性能会比ReentrantLock高出不少。在多线程读时互不影响,不像ReentrantLock即使是多线程读也需要每个线程获取锁。不过任何一个线程在写的时候就和ReentrantLock类似,其他线程无论读还是写都必须获取锁。需要注意的是同一个线程可以拥有 writeLock 与 readLock (但必须先获取 writeLock 再获取 .原创 2021-03-20 16:50:43 · 9399 阅读 · 1 评论 -
多线程同步器之CountDownLatch
文章目录CountDownLatch是什么核心方法构造方法常用的其他三个方法使用案例CountDownLatch是什么countDownLatch是在java1.5被引入,可以翻译为计数器。主要用于等待多个线程一起执行完成后继续下一步,Thread.join()有点类似核心方法构造方法CountDownLatch 值提供了一个构造方法,传入一个计数器的值常用的其他三个方法//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行public void await()原创 2021-03-06 20:44:06 · 1926 阅读 · 0 评论 -
SpringBoot+Apollo配置动态线程池
文章目录前言实现核心依赖配置文件实现代码前言尽管我们经过谨慎的评估,仍然不能够保证一次计算出来来的线程池参数是合适的,那么我们是否可以将修改线程池参数的成本降下来,这样至少可以发生故障的时候可以快速调整从而缩短故障恢复的时间呢?基于这个思考,我们是否可以将线程池的参数从代码中迁移到分布式配置中心上,实现线程池参数可动态配置和即时生效,线程池参数动态化前后的参数修改流程对比如下实现分布式配置中心这里使用的是Apollo核心依赖 <dependency> &l原创 2021-02-08 08:48:50 · 5015 阅读 · 0 评论 -
线程池在美团的最佳实践
文章目录一、写在前面1.1 线程池是什么二、线程池核心设计与实现2.1 总体设计2.2 生命周期管理2.3 任务执行机制2.3.1 任务调度2.3.2 任务缓冲2.3.3 任务申请2.3.4 任务拒绝2.4 Worker 线程管理2.4.1 Worker 线程2.4.2 Worker 线程增加2.4.3 Worker 线程回收三、线程池在业务中的实践3.1 业务背景3.2 实际问题及方案思考3.3 动态化线程池3.3.1 整体设计3.3.2 功能架构3.4 实践总结四、参考资料一、写在前面1.1 线程池转载 2021-02-04 21:20:01 · 1177 阅读 · 2 评论 -
Future异步回调详解
文章目录案例join实现FutureTaskGuava 的异步回调扩展案例在深入理解 异步回调模式前,我们以一个经典案例来说明,即数学家华罗庚先生的文章《统筹方法》,介绍了一个烧水泡茶的例子,文中提到最优的工序应该是下面这样用两个线程 T1 和 T2 来完成烧水泡茶程序,T1 负责洗水壶、烧开水、泡茶这三道工序,T2 负责洗茶壶、洗茶杯、拿茶叶三道工序,其中 T1 在执行泡茶这道工序时需要等待 T2 完成拿茶叶的工序这里实现方式有多中,我们先一最简单的线程汇总的join来实现join实现在编原创 2020-11-01 15:13:21 · 2634 阅读 · 2 评论 -
一次 parallelStream 引发的线程安全问题思考
前言之前 业务开发中 parallelStream用的很少,书中对他的介绍印象中也停留在线程安全中,所以在使用parallelStream的中途就没有考虑线程安全问题,然后就出现了如下诡异的线程安全问题问题代码 List<ClearProduct> clears = Lists.newArrayListWithExpectedSize(sizeCount); source.stream().parallel().forEach(s -> { /原创 2020-06-24 08:03:06 · 3396 阅读 · 0 评论 -
多线程实现阻塞队列及wait,notify,notifyall详解
首先我们实现一个阻塞式队列需要考虑的问题:队列采用什么存储: ArrayList队列存取之间的通信方式:使用wait和notify队列存取如何保准数据一致性问题:加锁synchronized实现代码:import java.util.ArrayList;import java.util.List;/** * @author WH * @version 1.0 * @da...原创 2019-10-11 22:11:39 · 420 阅读 · 0 评论 -
多线程设计模式:生产者-消费者
生产者,消费者:就好比厨师和食客,我们来看代码理解一下https://www.cnblogs.com/xiaoxi/p/7910868.htmlhttps://www.jianshu.com/p/71a5089afe13转载 2019-09-03 11:00:29 · 3108 阅读 · 0 评论 -
BlockingQueue
文章目录BlockingQueue接口的继承关系BlockingQueue(阻塞队列)特点BlockingQueue常用方法ArrayBlockingQueueArrayBlockingQueue简单使用LinkedBlockingQueuePriorityBlockingQueueSynchronousQueue基于BlockingQueue实现生产者消费者BlockingQueue接口的继承...原创 2019-12-14 23:25:19 · 626 阅读 · 0 评论 -
Java 线程池原理及四种常用的线程池使用
文章目录什么是线程池使用线程池的好处线程池的实现原理流程图分析源码分析线程池的使用什么是线程池线程池就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是继续放在线程池中,等待下一个任务。和连接池有点类似使用线程池的好处降低资源消耗。通过重复利用已创建的线程降低线程的创建和销毁造成的消耗提高相应速度。当任务到达时,任务可疑不需要等到...原创 2019-08-01 11:08:01 · 1040 阅读 · 0 评论 -
学习多线程前你必须知道的理论
文章目录同步(Synchronous)和异步(Asynchronous)并发(Concurrency)和并行(Parallelism)临界区阻塞(Blocking)和非阻塞(Non_Blocking)死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)并发的级别原子性(Atomicity)同步(Synchronous)和异步(Asynchronous)同步:同步和...原创 2019-07-23 21:51:56 · 305 阅读 · 0 评论 -
Java定时任务调度详解
原文传送门前言 在实际项目开发中,除了Web应用、SOA服务外,还有一类不可缺少的,那就是定时任务调度。定时任务的场景可以说非常广泛,比如某些视频网站,购买会员后,每天会给会员送成长值,每月会给会员送一些电影券;比如在保证最终一致性的场景中,往往利用定时任务调度进行一些比对工作;比如一些定时需要生成的报表、邮件;比如一些需要定时清理数据的任务等。本篇博客将系统的介绍定时任务调度,会涵盖T...转载 2019-07-09 14:07:05 · 551 阅读 · 0 评论 -
实现多线程的两种方式
1. 继承Thread类并重写run方法/** * @author WH * @version 1.0 * @date 2019/7/7 16:15 */public class MyThread extends Thread { @Override public void run () { for (int i = 0; i < 50; i++...原创 2019-07-07 17:01:17 · 1081 阅读 · 0 评论