java并发编程
文章平均质量分 76
寅灯
本人爱好互联网技术,乐观开朗,乐于助人!
展开
-
ThreadPoolExecutor 源码深度解析
ThreadPoolExecutor 源码深度解析原创 2022-06-30 12:40:29 · 204 阅读 · 0 评论 -
java的list排序
1、要排序的实体例子package com.xiangxue.jack.test;//实现Comparable<Students>public class Students implements Comparable<Students>{ private String name; private int score; public String getName() { return name; } public原创 2021-01-16 16:01:01 · 230 阅读 · 0 评论 -
并发编程Disruptor并发框架原理及使用(三十八)
并发编程Disruptor并发框架原理及使用应用背景和介绍 Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列,研发的初衷是 解决内部的内存队列的延迟问题,而不是分布式队列。基于 Disruptor 开发的系 统单线程能支撑每秒 600 万订单,2010 年在 QCon 演讲后,获得了业界关注。据目前资料显示:应用 Disruptor 的知名项目有如下的一些:Storm, Camel, Log4j2,还有目前的美团点评技术团队也有很多不少的应用,或者说有一些借鉴了原创 2021-01-03 15:20:53 · 189 阅读 · 0 评论 -
Java8 中新增的与并发编程相关的技术(三十七)
原子操作 CAS LongAdder JDK1.8 时,java.util.concurrent.atomic 包中提供了一个新的原子类:LongAdder。 根据 Oracle 官方文档的介绍,LongAdder 在高并发的场景下会比它的前辈——— —AtomicLong 具有更好的性能,代价是消耗更多的内存空间。 AtomicLong 是利用了底层的 CAS 操作来提供并发性的,调用了 Unsafe 类的 getAndAddLong 方法,该方法是个 native 方法,原创 2021-01-03 15:10:15 · 174 阅读 · 0 评论 -
java内存模型中锁的内存语义及种类(三十六)
java内存模型中锁的内存语义及种类锁的内存语义 当线程释放锁时,JMM 会把该线程对应的本地内存中的共享变量刷新到主 内存中。当线程获取锁时,JMM 会把该线程对应的本地内存置为无效。从而使得被 监视器保护的临界区代码必须从主内存中读取共享变量。如果我们回顾第一章的 VolatileCase,我们知道,为了让子线程可以及时看 到 ready 变量的修改,我们需要将 ready 变量以 volatile 来修饰。但是,当我们将程序做如下改造...原创 2021-01-01 13:12:25 · 132 阅读 · 0 评论 -
java内存模型 关键字 final 的内存语义(三十五)
java内存模型 关键字 final 的内存语义:在构造线程的类时,我们有种方式就是让类中所有的成员变量都不可变,利 用的就是 final 关键字,那么这个 final 为何可以做到呢?重排序这种优化动作对 构造方法,一样也是存在的。这就说明,一个成员变量加了 final 关键字后,JMM 一定是做了相关处理的。 final 的两个重排序规则 对应 final 域,编译器和处理器需要遵守两个重排序规则。我们以代码 cn.enjoyedu.ch9.semantics. FinalM原创 2020-12-31 14:08:16 · 237 阅读 · 2 评论 -
java内存模型关键字 volatile 详解(三十四)
java内存模型关键字 volatile 详解:volatile 特性 可以把对 volatile 变量的单个读/写,看成是使用同一个锁对这些单个读/写 操作做了同步可以看成所以 volatile 变量自身具有下列特性:可见性。对一个 volatile 变量的读,总是能看到(任意线程)对这个 volatile 变量最后的写入。 原子性:对任意单个 volatile 变量的读/写具有原子性,但类似于 volatile++ 这种复合操作不具有原子性...原创 2020-12-31 11:43:55 · 83 阅读 · 0 评论 -
并发编程happens-before语义详解(三十三)
并发编程happens-before语义详解:在 Java 规范提案中为让大家理解内存可见性的这个概念,提出了 happens-before 的概念来阐述操作之间的内存可见性。对应 Java 程序员来说,理 解 happens-before 是理解 JMM 的关键。 JMM 这么做的原因是:程序员对于这两个操作是否真的被重排序并不关心, 程序员关心的是程序执行时的语义不能被改变(即执行结果不能被改变)。因此, happens-before 关系本质上和 as-if-serial 语义原创 2020-12-31 11:30:51 · 236 阅读 · 0 评论 -
Java 内存模型存在的问题(三十二)
今天分享Java 内存模型存在的问题及如何解决:从抽象的角度来看,JMM 定义了线程和主内存之间的抽象关系:线程之间 的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内 存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。本地 内存是 JMM 的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存 器以及其他的硬件和编译器优化。Java 内存模型带来的问题 可见性问题 左边 CP...原创 2020-12-31 11:19:39 · 88 阅读 · 0 评论 -
Java内存模型底层实现原理(三十一)
Java内存模型又称JMM,其底层实现原理需要详细说一下,非常有利于技术的提高:JMM 基础-计算机原理 Java 内存模型即 Java Memory Model,简称 JMM。JMM 定义了 Java 虚拟机 (JVM)在计算机内存(RAM)中的工作方式。JVM 是整个计算机虚拟模型,所以 JMM 是隶属于 JVM 的。Java1.5 版本对其进行了重构,现在的 Java 仍沿用了 Java1.5 的版本。Jmm 遇到的问题与现代计算机中遇到的问题是差不多的。 物理计算机中的并原创 2020-12-31 10:27:33 · 118 阅读 · 0 评论 -
并发编程场景下的死锁和性能问题(三十)
概念是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信 而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统 处于死锁状态或系统产生了死锁。 举个例子:A 和 B 去按摩洗脚,都想在洗脚的时候,同时顺便做个头部按摩, 13 技师擅长足底按摩,14 擅长头部按摩。 这个时候 A 先抢到 14,B 先抢到 13,两个人都想同时洗脚和头部按摩,于 是就互不相让,扬言我死也不让你,这样的话,A 抢到 14,想要 13,B 抢到 13, 想要 14,在原创 2020-12-30 20:21:04 · 314 阅读 · 0 评论 -
并发编程场景下的线程安全性(二十九)
并发编程场景下的线程安全性:什么是线程安全性 在《Java 并发编程实战》中,定义如下: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程 将如何交替执行,并且在调用代码中不需要任何额外的同步或者协同,这个类都 能表现出正确的行为,那么就称这个类是线程安全的。 线程封闭 实现好的并发是一件困难的事情,所以很多时候我们都想躲避并发。避免并 发最简单的方法就是线程封闭。什么是线程封闭呢? 就是把对象封装到一个线程里,只有这一个线程能看到此对象。那么这个对原创 2020-12-30 19:55:20 · 84 阅读 · 0 评论 -
并发编程预定义线程池解析(二十八)
并发编程预定义线程池解析:FixedThreadPool 详解 创建使用固定线程数的 FixedThreadPool 的 API。适用于为了满足资源管理的 需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。 FixedThreadPool 的 corePoolSize 和 maximumPoolSize 都被设置为创建 FixedThreadPool 时指定的参数 nThreads。 当线程池中的线程数大于 corePoolSize 时,keepAliveTime原创 2020-12-30 19:33:27 · 109 阅读 · 0 评论 -
并发编程线程池及ThreadPoolExecutor类的原理解析(二十七)
并发编程线程池及ThreadPoolExecutor类的原理解析:为什么要用线程池? Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行 任务的程序都可以使用线程池。在开发过程中,合理地使用线程池能够带来 3 个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成 的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立 即执行。假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线 程中执行任务原创 2020-12-28 17:01:59 · 237 阅读 · 0 评论 -
阻塞队列 BlockingQueue原理解析(二十六)
队列队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行 删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受 限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。 在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。 因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能 最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。什么是阻塞队.原创 2020-12-28 18:35:13 · 451 阅读 · 0 评论 -
并发容器ConcurrentLinkedQueue原理解析(二十五)
并发容器ConcurrentLinkedQueue原理解析:无界非阻塞队列,它是一个基于链表的无界线程安全队列。该队列的元素 遵循先进先出的原则。头是最先加入的,尾是最近加入的。插入元素是追加到 尾上。提取一个元素是从头提取。 大家可以看成是 LinkedList 的并发版本,常用方法: concurrentLinkedQueue.add("c"); concurrentLinkedQueue.offer("d"); // 将指定元素插入到此队列的尾部。 concurrentLi原创 2020-12-29 21:55:44 · 154 阅读 · 0 评论 -
并发容器ConcurrentSkipList原理解析(二十四)
并发容器ConcurrentSkipList原理解析:ConcurrentSkipListMap 有序 Map ConcurrentSkipListSet 有序 Set TreeMap 和 TreeSet 使用红黑树按照 key 的顺序(自然顺序、自定义顺序) 来使得键值对有序存储,但是只能在单线程下安全使用;多线程下想要使键值对 按照 key 的顺序来存储,则需要使用 ConcurrentSkipListMap 和 ConcurrentSkipListSet,分别用以代替 Tr原创 2020-12-29 21:58:35 · 307 阅读 · 1 评论 -
线程安全的并发容器1.8版本的ConcurrentHashMap原理分析(二十三)
线程安全的并发容器1.8版本的ConcurrentHashMap原理分析:在 1.8 下的实现,与1.7相比:改进 改进一:取消 segments 字段,直接采用 transient volatile HashEntry<K,V>[] table 保存数据,采用 table 数组元素作为锁,从而实现了对缩小锁的粒度,进一 步减少并发冲突的概率,并大量使用了采用了 CAS + synchronized 来保证并发安 全性。改进二:将原先 table 数组+单向链表的数据结构,变原创 2020-12-28 09:07:00 · 120 阅读 · 0 评论 -
线程安全的并发容器1.7版本的ConcurrentHashMap原理分析(二十二)
线程安全的并发容器ConcurrentHashMap原理分析:原创 2020-12-27 21:25:33 · 112 阅读 · 0 评论 -
并发编程中1.7版本hashMap 死循环原理分析(二十一)
postgresql 插入数据 设置 自动生成主键为uuid格式:原创 2020-12-26 18:00:38 · 281 阅读 · 0 评论 -
并发编程 ReentrantLock 类的实现原理(二十)
并发编程 ReentrantLock 类的实现原理:锁的可重入 重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞, 该特性的实现需要解决以下两个问题。 1)线程再次获取锁。锁需要去识别获取锁的线程是否为当前占据锁的线程, 如果是,则再次成功获取。 2)锁的最终释放。线程重复 n 次获取了锁,随后在第 n 次释放该锁后,其 他线程能够获取到该锁。锁的最终释放要求锁对于获取进行计数自增,计数表示 当前锁被重复获取的次数,而锁被释放时,计数自减,当计数等于 0 时表原创 2020-12-22 20:56:47 · 89 阅读 · 0 评论 -
多线程异步操作子线程获取不到主线程request信息问题解决及源码解析
今天我们分析多线程场景下异步操作子线程获取不到主线程request信息问题解决及源码解析:一,共享request问题解决:1、先说使用,主线程核心设置代码:ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();RequestContextHolder.setRequestAttributes(servl原创 2020-12-16 15:48:44 · 9697 阅读 · 6 评论 -
并发编程 AbstractQueuedSynchronizer类Condition类之实现原理(十九)
并发编程 AbstractQueuedSynchronizer类Condition类之实现原理:Condition 的数据结构 等待队列是一个 FIFO 的队列,在队列中的每个节点都包含了一个线程引用, 该线程就是在Condition对象上等待的线程,如果一个线程调用了Condition.await() 方法,那么该线程将会释放锁、构造成节点加入等待队列并进入等待状态。事实 上,节点的定义复用了同步器中节点的定义,也就是说,同步队列和等待队列中 节点类型都是同步器的静态内部类。原创 2020-12-16 17:49:45 · 94 阅读 · 0 评论 -
并发编程 AbstractQueuedSynchronizer类共享锁之源码解析(十八)
并发编程 AbstractQueuedSynchronizer类共享锁之源码解析:一、共享式同步状态获取与释放 共享式获取与独占式获取最主要的区别在于同一时刻能否有多个线程同时 获取到同步状态。以读写为例,如果一个程序在进行读操作,那么这一时刻写操 作均被阻塞,而读操作能够同时进行。写操作要求对资源的独占式访问,而读操 作可以是共享式访问。 在 acquireShared(int arg)方法中,同步器调用 tryAcquireShared(int arg)方法尝 试获取同步状态tryAcquire原创 2020-12-16 16:09:40 · 184 阅读 · 0 评论 -
并发编程 AbstractQueuedSynchronizer 类实战之独占式可重入实现(十六)
并发编程 AbstractQueuedSynchronizer 类实战使用之独占式实现:public class SelfLock implements Lock { // 静态内部类,自定义同步器 private static class Sync extends AbstractQueuedSynchronizer { /*判断处于占用状态*/ @Override protected boolean isHeldExclus.原创 2020-12-14 11:33:55 · 119 阅读 · 0 评论 -
并发编程原子操作 AQS 思想之Lock锁的标准使用(十二)
今天我们分析并发编程原子操作 AQS 思想之Lock 的标准使用一、显式锁和 AQS:1、显式锁有了 synchronized 为什么还要 Lock? Java 程序是靠 synchronized 关键字实现锁功能的,使用 synchronized 关键字;将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。Lock 的标准用法:代码示例:public class LockCase { private Lock lock = new Reentr.原创 2020-12-13 20:07:04 · 227 阅读 · 2 评论 -
手动实现CAS 思想之 AtomicInteger 自增原理(十一)
1、手动实现CAS 思想之自增原理:public class HalfAtomicInt { private static AtomicInteger atomicI = new AtomicInteger(0); /*CAS递增方法实现*/ public void increament() { for (;;) {//死循环操作,直到成功为止 int i = getCount();//获取当前的值 boole原创 2020-12-13 13:11:04 · 518 阅读 · 0 评论 -
并发编程 AQS 思想之ReentrantReadWriteLock 锁的实现原理解析(二十一)
并发编程 AQS 思想之ReentrantReadWriteLock 锁的实现解析:原创 2020-12-22 20:58:39 · 111 阅读 · 0 评论 -
并发编程 AQS 思想之AbstractQueuedSynchronizer类的源码解析(十七)
并发编程 AQS 思想之AbstractQueuedSynchronizer类的源码解析:原创 2020-12-15 22:45:49 · 125 阅读 · 0 评论 -
并发编程 AQS 思想之AbstractQueuedSynchronizer 类原理解析(十五)
并发编程 AQS 思想之AbstractQueuedSynchronizer 类原理解析:原创 2020-12-13 22:27:28 · 122 阅读 · 0 评论 -
并发编程 AQS 思想之CLH 队列锁的 原理使用(十四)
并发编程 AQS 思想之CLH 队列锁的 原理使用:CLH 队列锁即 Craig, Landin, and Hagersten (CLH) locks。 CLH 队列锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程 仅仅在本地变量上自旋,它不断轮询前驱的状态,假设发现前驱释放了锁就结束 自旋。当一个线程需要获取锁时: 1. 创建一个的QNode,将其中的locked设置为true表示需要获取锁,myPred 表示对其前驱结点的引用2. 线程 A 对 tai.原创 2020-12-13 21:12:49 · 454 阅读 · 0 评论 -
并发编程 AQS 思想之Condition 接口 的标准使用(十三)
并发编程原子操作 AQS 思想之Condition 接口 的标准使用:任意一个 Java 对象,都拥有一组监视器方法(定义在 java.lang.Object 上), 主要包括 wait()、wait(long timeout)、notify()以及 notifyAll()方法,这些方法与 synchronized 同步关键字配合,可以实现等待/通知模式。Condition 接口也提供 了类似 Object 的监视器方法,与 Lock 配合可以实现等待/通知模式。Condit..原创 2020-12-13 20:34:42 · 141 阅读 · 0 评论 -
并发编程原子操作 CAS 思想(十)
什么是原子操作?如何实现原子操作? 假定有两个操作 A 和 B,如果从执行 A 的线程来看,当另一个线程执行 B 时, 要么将 B 全部执行完,要么完全不执行 B,那么 A 和 B 对彼此来说是原子的。 实现原子操作可以使用锁,锁机制,满足基本的需求是没有问题的了,但是 有的时候我们的需求并非这么简单,我们需要更有效,更加灵活的机制, synchronized 关键字是基于阻塞的锁机制,也就是说当一个线程拥有锁的时候, 访问同一资源的其它线程需要等待,直到该线程释放锁, 这里会有原创 2020-12-12 20:59:42 · 160 阅读 · 0 评论 -
线程的并发工具类之Callable、Future 和 FutureTask原理和使用(九)
Runnable 是一个接口,在它里面只声明了一个 run()方法,由于 run()方法返 回值为 void 类型,所以在执行完任务之后无法返回任何结果。 Callable 位于 java.util.concurrent 包下,它也是一个接口,在它里面也只声明 了一个方法,只不过这个方法叫做 call(),这是一个泛型接口,call()函数返回的 类型就是传递进来的 V 类型。 Future 就是对于具体的 Runnable 或者 Callable 任务的执行结果进行取消、查 询是否原创 2020-11-21 23:45:20 · 322 阅读 · 0 评论 -
线程的并发工具类之Semaphore原理和使用(八)
Semaphore Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协 调各个线程,以保证合理的使用公共资源。应用场景 Semaphore 可以用于做流 量控制,特别是公用资源有限的应用场景,比如数据库连接。假如有一个需求, 要读取几万个文件的数据,因为都是 IO 密集型任务,我们可以启动几十个线程 并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数 只有 10 个,这时我们必须控制只有 10 个线程同时获取数据库连接保存数据,否 则会原创 2020-11-21 23:42:23 · 111 阅读 · 0 评论 -
线程的并发工具类之CountDownLatch和CyclicBarrier原理和使用(七)
CountDownLatch闭锁,CountDownLatch 这个类能够使一个线程等待其他线程完成各自的工 作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动 所有的框架服务之后再执行。 CountDownLatch 是通过一个计数器来实现的,计数器的初始值为初始任务 的数量。每当完成了一个任务后,计数器的值就会减 1 (CountDownLatch.countDown()方法)。当计数器值到达 0 时,它表示所有的已 经完成了任务,然后在闭锁上等待 Cou原创 2020-11-21 23:40:31 · 145 阅读 · 0 评论 -
线程的并发工具类之forkjoin原理和使用(六)
Fork-Join java下多线程的开发可以我们自己启用多线程,线程池,还可以使用forkjoin, forkjoin 可以让我们不去了解诸如 Thread,Runnable 等相关的知识,只要遵循 forkjoin 的开发模式,就可以写出很好的多线程并发程序, 分而治之 同时 forkjoin 在处理某一类问题时非常的有用,哪一类问题?分而治之的问 题。十大计算机经典算法:快速排序、堆排序、归并排序、二分查找、线性查找、 深度优先、广度优先、Dijkstra、动态...原创 2020-11-21 23:36:38 · 124 阅读 · 0 评论 -
ForkJoin和冒泡排序组合实现的归并排序
package com.example.demo.studyThread.day4;import com.example.demo.studyThread.day3.MarkArray;import com.example.demo.studyThread.day3.SumArray;import java.util.Random;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTas.原创 2020-11-02 14:29:41 · 226 阅读 · 1 评论 -
线程间的协作 notify/notifyAll/wait关键字解析(五)
线程间的协作 线程之间相互配合,完成某项工作,比如:一个线程修改了一个对象的值, 而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程, 而最终执行又是另一个线程。前者是生产者,后者就是消费者,这种模式隔离了 “做什么”(what)和“怎么做”(How),简单的办法是让消费者线程不断地 循环检查变量是否符合预期在 while 循环中设置不满足的条件,如果条件满足则 退出 while 循环,从而完成消费者的工作。却存在如下问题: 1) 难以确保及时性。2)难以降原创 2020-11-06 09:56:22 · 140 阅读 · 0 评论 -
ThreadLocal 使用及源码详解(四)
与 Synchonized 的比较 ThreadLocal 和 Synchonized 都用于解决多线程并发訪问。可是 ThreadLocal 与 synchronized 有本质的差别。synchronized 是利用锁的机制,使变量或代码块 在某一时该仅仅能被一个线程訪问。而 ThreadLocal 为每个线程都提供了变量的 副本,使得每个线程在某一时间訪问到的并非同一个对象,这样就隔离了多个线 程对数据的数据共享。 Spring 的事务就借助了 ThreadLocal 类。原创 2020-11-21 23:33:13 · 155 阅读 · 1 评论