人在江湖之J.U.C 详解
文章平均质量分 94
JUC 包中的实用类为Java开发者提供了丰富的并发编程工具,使得多线程应用程序的开发更加简单、高效和安全。是当前 Java 程序员必备知识
没事儿写两篇
授之以鱼不如授之以渔
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
JUC ThreadLocal
在此,请大家先回顾一下我们在 JVM 专栏《JVM GC 垃圾收集器》一章中提到的几种引用的类型(强软弱虚),以及它们在 GC 时的特点,这样有助于理解该问题。其实 ThreadLocal 在我们上面的示例中的引用关系,除了在线程中(我们上面总结的引用关系图),还有就是在我们的 car 对象中,所以最终我们的引用图是这样的。原创 2024-02-07 08:39:30 · 1229 阅读 · 0 评论 -
JUC CompletableFuture
几乎所有的方法都返回了 CompletionStage ,这是链式调用的特性所有的方法参数都使用了函数式接口,一是可以 Lambda 表达式,二是根据不同的函数式接口的特性达到不同的执行要求不带 Async 的方法为同步方法,带 Async 的方法为异步方法这些方法分为 3 大类阶段成功才执行函数式接口(函数式接口的参数为当前阶段的结果)阶段失败才执行函数式接口(函数式接口的参数为当前阶段出现的异常)原创 2024-01-31 07:30:00 · 1185 阅读 · 0 评论 -
JUC Future 与 ForkJoin
工作窃取指的是允许空闲线程从繁忙线程的工作队列中窃取任务。对于 CPU 密集型的任务,并不是设置越多的线程性能越高,因为在计算时需要使用 CPU,极端情况下,CPU 是没有空闲时间的,如果线程数设置过多,反而由于线程之间对 CPU 资源的争抢造成不必要的上下文切换导致性能下降。在 Fork/Join 之前,我们在线程池中执行的线程之间是没有直接的关联的,这种情况下,如果我们某一个线程的执行需要另一个线程的执行结果,就没有办法实现,所有 JDK1.7 引入了 Fork/Join 框架。3. 造轮胎(1s);原创 2024-01-26 09:56:42 · 840 阅读 · 0 评论 -
JUC BlockingQueue(阻塞队列)
(这里要注意:出队是出的根元素,之后的元素会按出队规则进行移动,形成新的、符合其规则的完全二叉树)我们可以把它当做一个线程安全的容器,有了它,我们可以更简单且安全的进行在多线程下存取“数据”存取操作。补充说明:Delayed 的 getDelay 方法,其实就是判断是否到了执行时间,只要 getDelay 返回小于等于 0,则任务出队执行,否则继续阻塞等待。BlockingQueue 这么多方法,其实就两个操作,存和取。由于这里的知识太过零散,用文字的方式不好表达,这里总结为思维导图,通过图片分享出来。原创 2024-01-23 16:48:58 · 526 阅读 · 0 评论 -
JUC 线程池
日志反应的比较清楚,我们的线程池只有2个线程,线程2 执行了两个提交的任务,f1 的结果为任务返回的结果,f2 的结果为我们提交任务是传的结果,f3 不返回结果(因为 Runnable 接口的 run 方法返回值为 void)这里的线程名称格式为:pool-[虚拟机中线程池编号]-thread-[线程编号],如 pool-1-thread-1,在实际使用时我们最好自定义线程名称,以提高日志的可读性,避免日后排查日志无法第一时间确定执行的线程。如果没有则继续等待,直到有空闲线程执行。原创 2024-01-17 16:59:51 · 1202 阅读 · 0 评论 -
JUC CAS 和 原子操作类
AtomicStampedReference 引入了 stamp (版本号)来区别每次的修改,即便修改后的值与之前的某个状态的值一致,其版本号也是不同的。compareAndSet(int expect, int update) :expect 表示修改时的原值,update 表示要修改为的值,如果修改成功 方法返回 true,如果修改失败,方法返回 false。其是一种乐观锁的算法实现,本身不加锁。比如原值为 V=10,线程1修改值为 B = 5,线程2修改值为 b = 3,CAS 操作的过程为。原创 2024-01-15 09:22:15 · 1103 阅读 · 0 评论 -
JUC Lock 计数锁
Semaphore 在实际应用中其实使用得并不多,因为当资源较少的时候,可能造成大量线程阻塞。而且我们使用线程池的方式也可以达到这些效果,而且线程池的使用更简单。原创 2024-01-09 09:46:20 · 1017 阅读 · 0 评论 -
JUC Lock 读写锁
文章目录ReentrantReadWriteLock^1.5+^ 读写锁ReentrantReadWriteLock 继承关系图示例 1示例 2先获取读锁再获取写锁先获取写锁再获取读锁锁降级总结StampedLock^1.8+^ (邮戳锁)基本使用示例1示例2示例3StampedLock 源码文档上的示例ReentrantReadWriteLock1.5+ 读写锁对共享数据的查看、查询就是读,对共享数据的修改就是写,读时不会涉及共享数据的修改,不修改意味着多个线程读取的数据就不会变化,那么在此情况下多原创 2024-01-09 09:41:10 · 1227 阅读 · 0 评论 -
JUC AQS(AbstractQueuedSynchronizer)
1.5+/*** 等待队列的头,懒初始化的,在初始化后,只能通过 setHead 方法修改* 如果 head 节点的存在,则 head 的状态 waitStatus 不会是 Node.CANCELLED 的* 出队,就是从 head 出/*** 等待队列的尾部,懒初始化,初始化后只能通过 enq 方法添加新的等待节点/*** 同步器的状态* 通过 getState、setState、compareAndSetState 方法操作/** 标识节点为共享模式 */原创 2024-01-04 19:00:00 · 1077 阅读 · 0 评论 -
JUC Lock 锁入门
每一个锁关联一个线程持有者和计数器,当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;t1 线程优先获得锁,所以会打印,t2 线程尝试获得锁且等待5秒,t1线程在2秒后就会释放锁,所以t2获得了锁。简单的说就是当持有该锁的线程再次尝试获取该锁时,不会被阻塞(因为他已经持有该锁),而另外的线程尝试获取该锁时将被阻塞。比如:t1线程已经获得A锁,进而请求B锁,t2线程已经获得B锁,进而请求A锁。原创 2023-12-31 18:00:00 · 1214 阅读 · 1 评论 -
JUC JMM Java 内存模型
(就是存储在堆内存的变量:如 对象的字段、static 静态变量等都是多线程共享),数据就从内存向上,先到 L3,再到 L2,再到 L1,最后到寄存器进行 CPU 计算。如我们在 JMM 可见性中的示例,volatile 关键字可解决可见性问题,用于保证某个共享变量被某个线程操作后,其操作后的结果对其他线程立即可见(重新从主内存获取更新后的值到副本),我们在上面的 JMM 可见性中的示例就是 volatile 保证可见性的一个示例。是指同一个操作不可打断,在多线程情况下,操作不能被其他线程锁干扰。原创 2023-12-28 13:30:00 · 1077 阅读 · 0 评论 -
JUC Thread 基础回顾
文章目录并行与并发进程与线程线程切换上下文创建线程的方法用户线程和守护线程Thread 常用方法实例方法类方法线程打断示例线程的状态线程安全怎样尽可能的避免线程安全问题线程同步synchronized经典示例错误写法添加 synchronized 关键字最小化同步块最小化同步块,并进行重入判断Monitor 监视器(管程)Monitor 的核心组成部分锁优化轻量级锁自旋优化偏向锁偏向锁和轻量级锁锁消除wait 和 notify/notifyAll示例:点外卖并行与并发并发(concurrent):是指原创 2023-12-26 10:05:07 · 1222 阅读 · 0 评论
分享