
java并发
文章平均质量分 83
念何架构之路
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
java并发之CompletionService
本文介绍了如何通过阻塞队列和FutureTask实现任务按完成顺序获取结果的机制。通过使用ExecutorCompletionService,可以将任务提交到线程池中执行,并将完成的Future对象放入阻塞队列中。通过调用take或poll方法,可以从队列中获取已完成的Future,进而通过get方法获取任务结果。文章还提供了一个示例代码,展示了如何异步询价并将结果保存到数据库中。通过分析ExecutorCompletionService的源码,解释了任务完成时如何将Future放入队列,并确保先完成的任务原创 2025-05-19 23:16:27 · 350 阅读 · 0 评论 -
高性能队列Disruptor运用
Disruptor是一个高性能的内存队列,广泛应用于金融交易撮合系统。通过Maven依赖引入Disruptor库后,可以创建Disruptor实例并配置RingBuffer、生产者类型和等待策略。生产者通过RingBuffer发布事件,消费者则通过实现EventHandler或WorkHandler接口处理事件。Disruptor支持单生产者和多生产者模式,并允许配置多个消费者,消息可以被重复消费或仅由一个消费者处理。此外,Disruptor还支持按优先级顺序处理事件,确保高优先级任务优先执行。通过合理配置原创 2025-05-18 08:59:08 · 215 阅读 · 0 评论 -
线程池之ForkJoinPool
ForkJoinPool是Java中用于并行执行任务的线程池,它扩展了AbstractExecutorService类,支持任务拆分和任务窃取机制。ForkJoinPool通过将大任务拆分为更小的子任务,由工作线程并行执行,并允许工作线程从其他线程的任务队列中窃取任务以提高效率。任务需要继承RecursiveTask类并实现compute方法,定义任务的拆分逻辑。ForkJoinPool的构造函数支持自定义并行度、线程工厂、异常处理等参数。通过submit方法提交任务后,ForkJoinPool会根据任务的原创 2025-05-15 21:33:59 · 629 阅读 · 0 评论 -
阻塞队列之DelayQueue
DelayQueue 是一个支持延时获取元素的阻塞队列,内部使用优先队列 PriorityQueue 存储元素,且元素必须实现 Delayed 接口。元素在创建时可以指定延迟时间,只有在延迟期满时才能从队列中提取。队列中的元素不是按照先进先出的顺序,而是根据延迟时间排序,延迟最短的任务会优先执行。DelayQueue 通过 ReentrantLock 和 Condition 实现线程安全,并通过 leader 线程优化等待机制。put 和 offer 方法用于添加元素,take 方法用于获取并移除延迟期满的原创 2025-05-11 21:36:08 · 869 阅读 · 0 评论 -
阻塞队列之PriorityBlockingQueue
【代码】阻塞队列之PriorityBlockingQueue。原创 2025-05-07 22:32:08 · 322 阅读 · 0 评论 -
阻塞队列之SynchronousQueue
SynchronousQueue是一个没有数据缓冲的BlockingQueue生产者线程对其的插入操作put必须等待消费者的移除操作take。原创 2025-05-05 22:42:52 · 656 阅读 · 0 评论 -
阻塞队列之LinkedBlockingQueue
LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE,由于这个数值特别大,所以LinkedBlockingQueue 也被称作无界队列,代表它几乎没有界限,队列可以随着元素的添加而动态增长,但是如果没有剩余内存,则队列将抛出OOM错误。所以为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的时候建议手动传一个队列的大小。原创 2025-05-04 17:41:06 · 997 阅读 · 0 评论 -
阻塞队列之ArrayBlockingQueue
ArrayBlockingQueue是一个有界阻塞队列,内部用数组存储元素,初始化的需要指定容量大小,底层用ReentrantLock来保证线程安全.原创 2025-04-29 22:27:28 · 354 阅读 · 0 评论 -
java并发之ReentrantReadWriteLock
假如我们的状态值的32位二进制表达式为(0000111100000000 0000000000000101).当这个值与EXCLUSIVE_MASK进行and操作时,1 1为1,0 1或者 1 0都为0.所以我们就可以得到独占锁的值为.(00000000 00000000 0000000000000101).lock接口约束了ReadLock,ReadLcok又实现了具体的方法.并且他们都指向了一个关键的类.Sync.我们可以看到,它是一个抽象类,而且实现了Aqs.抽象类的特点就是从下而上的约束.原创 2025-04-27 22:26:17 · 381 阅读 · 0 评论 -
java并发之ReentrantReadWriteLock的写锁
ReentrantReadWriteLock是juc包下的一个锁工具类,可以同时获取读锁和写锁,读锁底层为共享锁,写锁底层为独占锁.读锁可以重复获取,写锁只可以有一个线程获取,并且读写锁互斥.读锁不可以升级为写锁.而写锁可以降级为读锁.是为了保证多线程情况下数据的可见性.原创 2025-04-23 22:54:15 · 756 阅读 · 0 评论 -
java并发之ReentrantReadWriteLock的读锁
ReentrantReadWriteLock是juc包下的一个锁工具类,可以同时获取读锁和写锁,读锁底层为共享锁,写锁底层为独占锁.读锁可以重复获取,写锁只可以有一个线程获取,并且读写锁互斥.读锁不可以升级为写锁.而写锁可以降级为读锁.是为了保证多线程情况下数据的可见性.原创 2025-04-22 22:58:19 · 580 阅读 · 0 评论 -
java并发之Semaphore
Semaphore是juc包下的一个锁工具类,通过获取许可来执行业务逻辑,比如实现限流.原创 2025-04-20 10:49:30 · 594 阅读 · 0 评论 -
java并发之CountDownLatch
从例子中可以看到很关键的两个方法.CountDownLatch的countDown()方法和await()方法.而且java没有特殊情况的话,是串行执行,所以我们就从countDown()方法为入口.解除自己心中的疑惑.没看错,是主线程.因为java天生支持多线程,我们不能以一个一个线程的执行来分析,当我们执行线程一和二的逻辑的时候,主线程已经执行到await方法了.接下来我们就直接去看await方法来破案吧.找到的子类实现以后,两个很关键的地方,一个是for循环,一个是cas操作.原创 2025-04-18 22:44:31 · 915 阅读 · 0 评论 -
异步调用之FutureTask
使用FutureTask实现异步泡茶喝,main线程可以获取烧水线程 清洗线程的执行结果,然后根据结果判断是否具备泡茶条件,如果具备泡茶条件在泡茶.启动Thread实例的run方法,会执行FutureTask实例的run方法,最终会执行到Callable实现的call方法.4:调用Thread实例的start()方法启动新线程,启动新线程的run()方法并发执行.其内部的执行过程为.1:创建一个Callable接口的实现类,并实现call方法,编写好异步执行的具体逻辑,并且可以有返回值.原创 2024-11-03 11:51:38 · 441 阅读 · 0 评论 -
异步回调之Join
总结下,join方法通过上面的源码可以看出,是不断通过检查线程是否存存活,来进行阻塞.直到被唤醒才会解除阻塞.而且join方法不能拿到返回结果,缺少很多的灵活性.所以join更多的停留在Demo演示上.Java中线程的合并流程是:假设线程A调用线程B的join()方法去合并B线程,那么线程A进入阻塞状态,直到线程B执行完成.A线程调用B线程的join方法,等待B线程执行完成,在B线程没有完成之前,A线程阻塞.A线程等待B线程执行一段时间,最长时间为millis 毫秒,超过后就会A线程重新执行.原创 2024-11-02 20:59:11 · 472 阅读 · 0 评论 -
高并发设计模式之生产者-消费者模式和Future模式
生产者和消费者是两个独立的并发体,生产者把制造出来的数据往缓冲区一放,就可以生产下一个数据.生产者基本上不用依赖于消费者的消费速度.如果生产过快,消费者可以平缓的进行处理.比如阻塞队列和MQ等就是生产者消费的例子.Future模式的核心思想是异步调用.有点类似于异步的Ajax请求. 当调用某个耗时的方法时,可以不急于立刻获取结果,而是让被调用者立刻返回一个契约,并且将耗时的任务放到另外的线程执行.后续在凭契约来获取结果.原创 2024-10-26 12:27:21 · 496 阅读 · 0 评论 -
并发设计模式之单例模式
单例模式加锁操作只有单例在第一次创建的时候才需要用到,之后的单例获取操作都没必要在加锁.所以可以先判断单例对象是否被初始化,如果没有在加锁初始化.参考如下.缺点:单例对象在类被加载的时候,实例就直接被初始化了.很多时候在类被加载的时候并不需要进行单例初始化.所以需要对单例的初始化予以延迟.参考代码如下.3:进入临界区后,再一次检查对象是否被初始化,如果没有被初始化就初始化一个实例,相反就返回这个实例.这是第二次检查.1:检查单例对象是否被初始化,如果初始化,立即返回单例对象.这是第一次检查.原创 2024-10-20 11:12:57 · 922 阅读 · 0 评论 -
BlockingQueue详解
如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。LinkedBlockingDeque 是一个双端队列,在它为空的时候,一个试图从中抽取数据的线程将会阻塞,无论该线程是试图从哪一端抽取数据。一个线程往阻塞队列里放资源.另一个线程进行消费.如果队列满的话,放入的线程会被阻塞.相反.如果队列为空,消费的线程就会被阻塞.。原创 2024-10-14 23:11:27 · 1282 阅读 · 0 评论 -
ReentrantReadWriteLock源码讲解
此函数用于获取写锁,首先会获取state,判断是否为0,若为0,表示此时没有读锁线程,再判断写线程是否应该被阻塞,而在非公平策略下总是不会被阻塞,在公平策略下会进行判断(判断同步队列中是否有等待时间更长的线程,若存在,则需要被阻塞,否则,无需阻塞),之后在设置状态state,然后返回true。否则,将设置当前线程对应的HoldCounter对象的值.HoldCounter主要有两个属性,count和tid,其中count表示某个读线程重入的次数,tid表示该线程指定线程id.用来唯一标识一个线程.原创 2024-10-12 23:43:10 · 1190 阅读 · 0 评论 -
ReentrantLock源码
现在真的很喜欢孙中山的自勉联,愿乘风破万里浪,甘面壁读十年书.普普通通一句话,好的心态,面对世俗的质疑,对前方的执着. 弃医从文,不仅仅是魄力,更是认知的转变.更是知与行的诠释.愿吾自立自强,不朽.t1线程的lock操作 -> t2线程的lock操作 -> t3线程的lock操作 -> t1线程的unlock操作 -> t2线程的unlock操作 -> t3线程的unlock操作.从lock方法的源码可知,每一次都尝试获取锁,而并不会按照公平等待的原则进行等待,让等待时间最久的线程获得锁。原创 2024-10-07 19:18:29 · 1353 阅读 · 0 评论 -
AQS机制详解
执行案例的运行结果.(其中之一) 线程t1先执行lock操作,获取锁.然后线程t2执行lock操作.然后t1进行unlock操作,然后t2获取锁成功,接着执行unlock操作. t1线程调用lock.lock方法,方法调用顺序.t2线程调用lock.lock方法,其方法调用顺序. 最后的结果是被阻塞.源码如下. t1线程调用lock.unlock,其方法调用顺序.t1线程中调用lock.unlock后,经过一系列的调用,最终的状态是释放了许可,因为调用了LockSupport.unpark。这时,t2线程原创 2024-10-05 12:46:24 · 810 阅读 · 0 评论 -
AQS讲解
AQS是一个并发的得同步器.JUC包下的ReentrantLock,Semaphore,ReentrantReadWriteLock,SynchronousQueue,FutureTask等底层都是基于AQS实现的.我们也可以通过AQS实现自己的并发工具类.原创 2024-10-04 19:51:04 · 1139 阅读 · 0 评论 -
Semaphore源码讲解
Semaphore称为计数信号量,当线程来访问资源的时候,只有获得许可才可以成功来访问资源.原创 2024-10-01 10:40:49 · 1516 阅读 · 0 评论 -
CyclicBarrier源码分析
说明: 由于ReentrantLock的默认采用非公平策略,所以在dowait函数中调用的是ReentrantLock.NonfairSync的lock函数,由于此时AQS的状态是0,表示还没有被任何线程占用,故main线程可以占用,之后在dowait中会调用trip.await函数,最终的结果是条件队列中存放了一个包含main线程的结点,并且被禁止运行了,同时,main线程所拥有的资源也被释放了,可以供其他线程获取。头节点与尾节点均指向它。此函数的作用是损坏当前屏障,会唤醒所有在屏障中的线程。原创 2024-09-22 14:35:56 · 888 阅读 · 0 评论 -
CountDownLatch源码分析
从源码可知,其底层是由AQS提供支持,所以其数据结构可以参考AQS的数据结构,而AQS的数据结构核心就是两个虚拟队列: 同步队列sync queue 和条件队列condition queue,不同的条件会有不同的条件队列。CountDownLatch典型的用法是将一个程序分为n个互相独立的可解决任务,并创建值为n的CountDownLatch。当每一个任务完成时,都会在这个锁存器上调用countDown,等待问题被解决的任务调用这个锁存器的await,将他们自己拦住,直至锁存器计数结束。原创 2024-09-21 22:08:07 · 723 阅读 · 0 评论