并发编程
文章平均质量分 91
大树~~
哦
展开
-
JUC-并发编程22-ThreadLocal、InheritableThreadLocal与TransmittableThreadLocal
在多线程编程中,我们常常需要在线程之间传递上下文信息。Java 提供了和来帮助管理线程局部变量,但在某些场景下,如线程池和异步执行中,这些工具存在一些局限性。让我们详细探讨这些问题的发展历程,并介绍最终的解决方案。在多线程编程中,和 `InheritableThreadLocal解决了线程局部变量的问题,但在复杂的线程池和异步执行场景下,这些工具存在局限性。通过捕获和恢复上下文信息,并包装线程池和任务,确保上下文的正确传递和清理,是一种有效的解决方案。原创 2024-06-10 18:46:47 · 1057 阅读 · 0 评论 -
JUC-并发编程21-常用并发设计模式
思考:在一个线程 T1 中如何正确安全的终止线程 T2?错误思路1:使用线程对象的 stop() 方法停止线程stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁, 其它线程将永远无法获取锁。错误思路2:使用 System.exit(int) 方法停止线程目的仅是停止一个线程,但这种做法会让整个程序都停止正确思路:利用Java线程的中断机制。原创 2024-05-01 22:39:46 · 826 阅读 · 0 评论 -
JUC-并发编程20-ForkJoin工作原理解析
传统线程池ThreadPoolExecutor有两个明显的缺点:一是无法对大任务进行拆分,对于某个任务只能由单线程执行;二是工作线程从队列中获取任务时存在竞争情况。这两个缺点都会影响任务的执行效率。为了解决传统线程池的缺陷,Java7中引入Fork/Join框架,并在Java8中得到广泛应用。Fork/Join框架的核心是ForkJoinPool类,它是对AbstractExecutorService类的扩展。原创 2024-04-30 00:51:02 · 447 阅读 · 0 评论 -
JUC-并发编程19-定时任务&定时线程池-ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor用来处理延时任务或定时任务。原创 2024-04-29 00:03:55 · 444 阅读 · 0 评论 -
JUC-并发编程18-线程池深入分析-ThreadPoolExecutor-2
前面我们一起学习了Java中线程池的体系结构、构造方法和生命周期,本章我们一起来学习线程池中普通任务到底是怎么执行的。1、案例示例我们创建一个线程池,它的核心数量为5,最大数量为10,空闲时间为1秒,队列长度为5,拒绝策略打印一句话。代码如下:public class ThreadPoolTest01 { public static void main(String[] args) { //核心数量为5,最大数量为10,空闲时间为1秒,队列长度为5,拒绝策略打印一句话。原创 2021-01-12 20:46:05 · 268 阅读 · 0 评论 -
JUC-并发编程17-线程池深入分析-ThreadPoolExecutor-1
1、简介ThreadPoolExecutor的构造方法是创建线程池的入口,虽然比较简单,但是信息量很大,由此也能引发一系列的问题,同样地,这也是面试中经常被问到的问题,下面只是列举了一部分关于ThreadPoolExecutor构造方法的问题。2、构造方法...原创 2020-10-27 21:36:25 · 280 阅读 · 0 评论 -
JUC-并发编程16-线程池深入分析-体系结构
1、简介上一节我们自己手动写了一个线程池,但是它是不支持带返回值的任务的,那么,我们自己能否实现呢?必须可以。2、对比无返回值的任务提交了就完事,主线程并Care它到底没有执行完,并不关心它是不是抛出异常,主线程提交线程到线程池中,其余什么都不管。有返回值的任务就不一样了,主线程首先要提交任务到线程池中,它需要使用到任务执行的结果,所以它必须等到任务执行完毕才能拿到任务执行的结果。那么,为什么不直接在execute的时候就等待任务执行完毕呢?这样的话那不就是串行了,线程池就没有啥意义了。原创 2020-08-31 15:04:29 · 169 阅读 · 0 评论 -
JUC-并发编程15-手写一个线程池
1、简介线程池是java并发编程中经常使用的技术,那么自己如何动手写一个线程池呢?2、属性分析线程池,首先有要一个池子来放线程,而线程又是用来执行任务的。首先,线程池中的线程应该是有类别的,有的线程是核心线程,有的是非核心线程,所以我们需要对这个两个类别线程数量来标记,就我们常说的coreSize和最大线程数量maxSize。当线程池中线程数未达到核心线程数coreSize时,来一个任务加一个线程是可以的,也可以提高任务执行的效率。 当线程池中线程数达到核心线程数后,得控制一下线程的数量原创 2020-08-27 17:50:30 · 161 阅读 · 0 评论 -
JUC-并发编程14-CyclicBarrier栅栏
1、简介CyclicBarrier,回环栅栏,它会阻塞一组线程直到这些线程同时达到某个条件才继续执行。它与CountDownLatch很类似,但又不同,CountDownLatch需要调用countDown()方法触发事件,而CyclicBarrier不需要,它就像一个栅栏一样,当一组线程都到达了栅栏处才继续往下走。...原创 2020-08-27 11:12:48 · 200 阅读 · 0 评论 -
JUC-并发编程13-CountDownLatch倒计时器
1、简介CountDownLatch,可以翻译为倒计时器,但是似乎不太准确,它的含义是允许一个或多个线程等待其它线程的操作执行完毕后再执行后续的操作。CountDownLatch的通常用法和Thread.join()有点类似,等待其它线程都完成后再执行主任务。2、继承关系CountDownLatch中只包含了Sync一个内部类,它没有公平/非公平模式,所以它算是一个比较简单的同步器了。3、内部syncprivate static final class Sync extends A原创 2020-08-20 16:31:09 · 237 阅读 · 0 评论 -
JUC-并发编程12-Semaphore信号量
1、简介Semaphore,信号量,他保存了一系列的许可(permits),每次调用acquire()都将消耗一个许可,每次调用release()都将归还一个许可。2、特性Semaphore通常用于限制同一时间对共享资源的访问次数上,也就是常说的限流。3、继承关系Semaphore中包含了一个实现AQS的同步器Sync,以及它的两个子类FairSync和NonFairSync,这说明Semaphore也是区分公平模式和非公平模式的。4、内部类Syncabstract sta原创 2020-08-19 11:59:34 · 214 阅读 · 0 评论 -
JUC-并发编程11-ReentrantReadWriteLock读写锁
读写锁是一种特殊的锁,它把对共享资源的访问分为读访问和写访问,多个线程可以同时对共享资源进行读访问,但是同一时间只能有一个线程对共享资源进行写访问,使用读写锁可以极大地提高并发量。读写锁实际维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得其并发性比独占式锁(排他锁)有了很大的提升。为什么需要读写锁?通过前面文章的学习,我们知道了ReentrantLock(下文简称:RLock)对象了。Rlock比起synchronized(下文简称Sync)来说有三个优点:RLock可以被中断;RLock原创 2020-08-18 18:19:03 · 303 阅读 · 0 评论 -
JUC-并发编程10-各种锁名称整理
1、公平锁/非公平锁公平锁,是指按照线程申请的顺序获取锁。非公平锁,是指不是按照线程申请的顺序获取锁,有可能后申请的线程反而先获取到锁,假如先来的线程一直获取不到锁,会造成锁饥饿现象。2、可重入锁是指一个线程获取锁之后再尝试获取锁时会自动获取锁,可重入锁的优点是避免死锁。ReentrantLock和synchronized都是可重入锁。3、独享锁/共享锁独享锁,是指锁一次只能被一个线程持有。共享锁,是指锁一次可以被多个线程持有。ReentrantLock和synchronized都原创 2020-07-20 17:11:28 · 257 阅读 · 0 评论 -
JUC-并发编程-09-阻塞队列BlockingQueue之-DelayQueue
DelayQueue队列中每个元素都有个过期时间,并且队列是个优先级队列,当从队列获取元素时候,只有过期元素才会出队列。1、继承结构从继承体系可以看到,DelayQueue实现了BlockingQueue,所以它是一个阻塞队列。另外,DelayQueue还组合了一个叫做Delayed的接口,DelayQueue中存储的所有元素必须实现Delayed接口。那么,Delayed是什么呢?...原创 2020-07-20 16:31:52 · 177 阅读 · 0 评论 -
JUC-并发编程-08-阻塞队列BlockingQueue之-PriorityBlockingQueue
PriorityBlockingQueue是一个支持优先级的无界阻塞队列,直到系统资源耗尽。默认情况下元素采用自然顺序升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。但需要注意的是不能保证同优先级元素的顺序。PriorityBlockingQueue也是基于最小二叉堆实现,使用基于CAS实现的自旋锁来控制队列的动态扩容,保证了扩容操作不会阻塞take操作的执行。我们在数据结构地原创 2020-07-13 22:10:12 · 214 阅读 · 0 评论 -
JUC-并发编程-09-阻塞队列BlockingQueue之LinkedBlockingQueue
LinkedBlockingQueue和ArrayBlockingQueue都是BlockingQueue的实现,都是阻塞队列。本期将学习LinkedBlockingQueue。1、继承关系2、属性介绍 static class Node<E> { //存放数据 E item; //下一个指针 所以说是单向链表 Node<E> next; Node(E x) { item = x; } } //聊.原创 2020-07-09 16:34:30 · 166 阅读 · 0 评论 -
JUC-并发编程-08-阻塞队列BlockingQueue之-ArrayBlockingQueue
1、概述我们在并发编程中,通常需要线程安全的队列。线程安全的队列分为两种:阻塞队列,使用锁来实现 非阻塞队列,使用CAS来实现。阻塞队列在实际应用中非常广泛,许多消息中间件中定义的队列,通常就是一种“阻塞队列”。其使用场景一般是在 “生产者-消费者” 模式中,用于线程之间的数据交换或系统解耦。“生产者-消费者”这种模式中,“生产者” 和 “消费者” 是相互独立的,两者之间的通信需要依靠一个队列。这个队列就是要说的阻塞队列。引入“阻塞队列”的最大好处就是解耦,在软件工程中,“高内聚,低耦合”是进行原创 2020-07-08 12:11:20 · 199 阅读 · 0 评论 -
JUC-并发编程-07-AtomicInteger源码分析
在多线程编程下,原子类操作必不可少。在juc下面也有为我们提供。如下图:本期以atomicInteger为例,学习源码。1、继承关系从继承关系来看,是没有什么特殊操作的,那么他是如何保证原子操作的。我们下面继续看。首先介绍一下原子操作:原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程上下文切换。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分,将整个操作视作一个整体是原子.原创 2020-07-07 15:25:36 · 169 阅读 · 0 评论 -
JUC-并发编程-06-HashMap与CurrentHashMap
本期学习hashMap与currentHashMap一个是我们在单线程的常用的集合框架,但是对于多线程的情况下就不在适用,所以juc下,有个CurrentHashMap。两个比较学习。后面再做个总结。本次学习是基于1.81、HashMap1.1 数据结构1.1.1 继承关系是Map接口的具体实现。1.1.2 属性介绍//默认初始容量-必须为2的幂static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//最大容量,如原创 2020-07-06 12:11:07 · 542 阅读 · 0 评论 -
JUC-并发编程-05-lock原理-AQS
本篇主要讲了lock的原理其实就是AQS,源码为证: ReentrantLock把所有Lock接口的操作都委派到一个Sync类上,该类继承了AbstractQueuedSynchronizer。 Sync又有两个子类:static final class NonfairSync extends Syncstatic final class FairSync extends Sync显然是为了支持公平锁和非公平锁而定义,默认情况下为非公平锁。非公平锁tryAcquire的...原创 2020-06-24 14:34:19 · 289 阅读 · 0 评论 -
JUC-并发编程-04-synchronized原理及应用
1、基本使用Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:原子性:确保线程互斥的访问同步代码; 可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的“对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或assign操作初始化变量值”来保证的; 有序性:有效解决重排序问题..原创 2020-06-11 18:25:57 · 341 阅读 · 0 评论 -
JUC-并发编程-03-volatile应用
java代码在编译后会变成java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,java中所使用的的并发机制依赖与JVM的实现和CPU的指令。1、volatile的应用在多线程并发编程的中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,他在多处理器开发中保证了共享资源的“可见性”。如何volatile变量修饰符使用恰当的话,它比synchronized的使用执行成本更低,因为它不会引起原创 2020-06-11 12:18:46 · 185 阅读 · 0 评论 -
JUC-并发编程-02-java内存模型JMM
最近思考了一下,要学习并发编程,应该先把JMM的知识点熟悉,后面才好学习。话不多说步入正题。、1、概述:Java线程之间的通信对程序员完全透明,内存可见性问题很容易困扰Java程序员,本章将揭开Java内存模型神秘的面纱。本章大致分4部分:Java内存模型的基础,主要介绍内存模型相关的基本概念;Java内存模型中的顺序一致性,主要介绍重排序与顺序一致性内存模型;同步原语,主要介绍3个同步原语(synchronized、volatile和final)的内存语义及重排序规则在处理器中的实现;Java内存原创 2020-06-10 17:04:20 · 300 阅读 · 0 评论 -
JUC-并发编程-01-并发的挑战
并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题、死锁的问题,以及受限于硬件和软件的资源限制问题,本章会介绍几种并发编程的挑战以及解决方案。...原创 2020-06-08 18:05:27 · 177 阅读 · 0 评论