
Java并发
文章平均质量分 92
SuZhan7710
于道各努力,千里自同风
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
ThreadLocal 核心原理
上述代码也说明,通过 ThreadLocal 为每个线程保存的本地变量不是存储在 ThreadLocal 实例中,而是存储在调用线程的 threadLocals 变量中,它的类型为 ThreadLocal 中的一个内部类 ThreadLocalMap,ThreadLocal 是一个壳子,真正的存储结构是 ThreadLocal 里有 ThreadLocalMap 这么个内部类,实现的类似 map 的功能。同时,删除 Thread-B 线程中的本地变量后,不会影响 Thread-A 线程中保存的本地变量。原创 2023-04-05 14:33:03 · 787 阅读 · 2 评论 -
ReentrantLock 核心原理
FairSync 类中的 lock 方法会调用 AQS 的 acquire 方法,AQS 的 acquire 方法又会调用 tryAcquire 方法,而 AQS 中的 tryAcquire 方法实际上是基于子类实现的,因此,此时调用的还是 FairSync 类的方法。不可中断锁指线程在抢占锁的过程中不能被中断。非公平锁的核心就是对抢占锁的所有线程都是不公平的,在多线程并发环境中,每个线程在抢占锁的过程中都会先直接尝试抢占锁,如果抢占锁成功,就继续执行程序的业务逻辑,如果抢占失败,就会进入等待队列中排队。原创 2023-04-01 21:25:19 · 862 阅读 · 0 评论 -
AQS 核心原理
一、AQS 核心数据结构AQS 内部主要维护了一个 FIFO(先进先出)的双向链表。AQS 内部维护的双向链表中的各个节点分别指向直接前驱节点和直接的后继节点。所以,在 AQS 内部维护的双向链表可以从其中任意一个节点遍历前驱节点和后继节点。链表中的每个节点其实都是对线程的封装,在并发场景下,如果某个线程竞争锁失败,就会被封装成一个 Node 节点加入 AQS 队列的末尾。当获取到锁的线程释放锁后,会从 AQS 队列中唤醒一个被阻塞的线程。同时,在 AQS 中维护一个使用 volatile 修饰的变量原创 2023-03-30 20:03:57 · 1536 阅读 · 1 评论 -
synchronized 核心原理
同时为了满足 JVM 中对象的起始地址必须是 8 的整数倍的要求,对象在 JVM 堆区中的存储结构还会有一部分对齐填充位。一个类的类元信息会存储在 JVM 的方法区中,对象头的类型指针会指向存储方法区中的类元信息。类元信息:类元信息在类编译期间放入方法区,里面放置了类的基本信息,包括类的版本、字段、方法、接口以及常量池表(Constant Pool Table)。原创 2023-03-25 13:04:36 · 1346 阅读 · 0 评论 -
volatile 核心原理
当一个线程修改了 volatile 修饰的共享变量之后,修改后的共享变量的值会立刻刷新到主内存,其他线程每次都从主内存中读取 volatile 修饰的共享变量,这就保证了使用 volatile 修饰的共享变量对线程的可见性。volatile 虽然能够保证数据的可见性和有序性,但是无法保证数据的原子性。volatile 在内存语义上有两个作用,一个作用是保证被 volatile 修饰的共享变量对每个线程都是可见的,当一个线程修改了被 volatile 修饰的共享变量之后,另一个线程能够立刻看到修改后的数据。原创 2023-03-20 10:01:03 · 385 阅读 · 0 评论 -
Java 内存模型
Java 内存模型规定了所有的变量都存储在主内存中,也就是存储在计算机的物理内存中,每个线程都有自己的工作内存,用于存贮线程私有的数据,线程对变量的所有操作都需要在工作内存中完成。对于线程工作内存与主内存之间的数据交互,JMM 定义了一套交互协议,规定了一个变量从主内存中复制到工作内存中,以及从工作内存同步到主存中的实现细节。Java 内存模型简称 JMM,是 Java 中为了解决可见性和有序性问题而制定的一种编程规范和规则,与 JVM 实实在在的内存结构不同,JMM 只是一种编程规范和规则。原创 2023-03-20 19:44:47 · 536 阅读 · 0 评论 -
Happens-Before 原则
在 JMM 中,定义了一套 Happens-Before 原则,用于保证程序在执行过程中的可见性和有序性。Happens-Before 原则主要包括程序次序原则、volatile 变量原则、传递原则、锁定原则、线程启动原则、线程总结原则、线程中断原则和对象终结原则。在JMM中, 如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。原创 2023-03-21 18:55:16 · 971 阅读 · 0 评论 -
并发编程中的锁
如果数据被其他线程修改过,则当前线程会尝试再次读取数据,检测数据是否被其他线程修改过,如果再次检测的结果仍然为数据已经被其他线程修改过,则会再次尝试读取数据,如此反复,直到检测到的数据没有被其他线程修改过。最后,线程 3 被唤醒并获取锁,执行完任务释放锁。例如,存在三个线程,分别为线程 1 、线程 2 和线程 3 ,在线程 1 和线程 2 抢占锁的过程中,线程 1 获取到锁,线程 2 阻塞等待。例如,线程 A 在执行任务的过程中获取锁,在后续执行任务的过程中,如果遇到抢占同一个锁的情况,则也会再次获取锁。原创 2023-03-19 10:18:42 · 448 阅读 · 0 评论 -
CompletableFuture异步编排
Future 是 Java 5 添加的类,用来描述一个异步计算的结果。你可以使用 isDone 方法检查计算是否完成,或者使用 get 阻塞住调用线程,直到计算完成返回结果,你也可以使用 cancel 方法停止任务的执行。虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。原创 2022-08-21 15:17:51 · 389 阅读 · 0 评论 -
关于AtomicInteger的一些见解&底层分析
目录1. 前言2. CAS2.1 为什么要用CAS呢?2.2 CAS的一些缺点3. AtomicInteger相关源码3.1 应用场景1. 前言Java中对基本类型的变量的赋值和读取是原子操作,如 i = 1 这样的是原子操作,但 j = i,j++ 都不是原子操作,它们都进行了多次原子操作,可能会出现线程安全的问题,所以AtomicInteger就应运而生了,它是一个原子类,可以解决我们在多线程环境下 i++ 的线程安全问题。2. CASAtomicInteger是对int类型的一个封装,提供原子原创 2021-12-27 21:59:12 · 730 阅读 · 1 评论 -
Synchronized关键字及锁升级的讲解
目录1. 锁的类型1.1 乐观锁1.2 悲观锁1.3 Markword2. 锁升级无锁偏向锁轻量级锁重量级锁1. 锁的类型1.1 乐观锁乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。1.2 悲观锁悲观锁:就是悲观思想,总是假设最坏原创 2021-12-30 16:11:58 · 710 阅读 · 2 评论 -
AbstractQueuedSynchronizer源码解析(上)
目录一、摘要二、AQS2.1 类定义2.2 基本属性2.2.1 简单属性2.1.2 共享锁和排它锁的区别2.1.3 同步队列属性2.1.4 条件队列的属性2.1.5 Node2.3 Condition三、同步器的状态一、摘要队列同步器AbstractQueuedSynchronizer,是用来构建锁或者其他同步组件的基础框架,它使用了一个 int 成员变量表示同步状态,通过内置的 FIFO 队列来完成资源获取线程的排队工作。同步器的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方原创 2022-01-02 13:19:34 · 535 阅读 · 0 评论 -
AbstractQueuedSynchronizer源码解析(下)
目录一、获取锁下面让我们步入正轨,谈谈如何获取锁以及释放锁。独占式(排他式)获取同步状态:acquire(), addWaiter(), enq(), acquireQueued();独占式释放同步状态:release();共享式获取同步状态:acquireShared(), doAcquireShared(), setHeadAndPropagate();共享式释放同步状态:releaseShared(), doReleaseShared();一、获取锁获取锁最直观的感受就是使用 L原创 2022-01-02 23:24:40 · 804 阅读 · 0 评论 -
ReentrantLock源码解析
目录一、ReentrantLock1.1 注释1.2 结构1.2.1 Lock 接口1.2.2 构造器1.2.3 Sync1.2.3.1 nonfairTryAcquire方法1.2.3.2 tryRelease方法1.2.4 FairSync 公平锁1.2.5 NonfairSync 非公平锁二、归纳总结2.1 lock 加锁2.2 tryLock 尝试加锁2.3 unlock 释放锁一、ReentrantLock1.1 注释ReentrantLock 叫做可重入互斥锁可重入的意思是同一个线程可以原创 2022-01-03 14:57:32 · 698 阅读 · 2 评论 -
Java 守护线程
目录一、什么是守护线程二、为什么需要守护线程三、如何使用四、守护线程的作用及应用场景一、什么是守护线程在说守护线程之前,我们先说一下什么是用户线程。用户线程:我们平常创建的普通线程。守护线程(即 Daemon thread):是个服务线程,用来服务于用户线程;不需要上层逻辑介入,当然我们也可以手动创建一个守护线程。在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出。二、为什么需要守护线程存在任意一个用户线程的时候,JVM就不会退出。那么JVM 程序在什么情况下能够正常原创 2022-01-14 22:50:21 · 760 阅读 · 4 评论 -
ThreadPoolExecutor 线程池相关介绍
目录一、介绍1.1> 为什么要用线程池1.2> 线程池工作流程1.3> 线程池的代码用例二、源码解析——构造函数2.1> 线程池的构造函数及类的继承关系2.2> Executors提供的线程池模板2.3> 拒绝策略的实现2.4> 任务队列BlockingQueue的实现一、介绍线程池我们在工作中经常会用到。在请求量大时,使用线程池,可以充分利用机器资源,增加请求的处理速度。1.1> 为什么要用线程池使用线程池可以减少创建和销毁线程的次数,每个工作线程原创 2022-02-04 18:48:03 · 721 阅读 · 0 评论