
多线程
张伯毅
某厂技术,Apache DolphinScheduler Committer.
专注于调度&实时&大数据体系~
展开
-
并发编程——原子性,可见性和有序性
1、原子性即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。原子性就像数据库里面的事务一样,他们是一个团队,同生共死。2、可见性可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。3、有序性即程序执行的顺序按照代码的先后顺序执行。...原创 2021-07-04 15:53:50 · 239 阅读 · 0 评论 -
Synchronized注意事项
Table of Contents1.概述1.1实现方式1.2使用方式2.对象内部结构2.1对象内部结构2.2 Mark Word 在 32 位 JVM 中存储内容2.3Mark Word 在 64 位 JVM 中存储内容 [ 待考证 ]3.锁升级过程4. 什么时候用自旋锁什么时候用系统锁?5.为什么Synchronized不能加在String和Integer等基本包装类型上1.概述1.1实现方式synchronized 是 JVM 内置...原创 2020-05-14 17:48:38 · 2866 阅读 · 0 评论 -
不懂什么是 Java 中的锁?看看这篇你就明白了!
Java 锁分类Java 中的锁有很多,可以按照不同的功能、种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述 从线程是否需要对资源加锁可以分为悲观锁和乐观锁 从资源已被锁定,线程是否阻塞可以分为自旋锁 从多个线程并发访问资源,也就是 Synchronized 可以分为无锁、偏向锁、轻量级锁和重量级锁 从锁的公平性进...转载 2020-01-30 19:53:06 · 1079 阅读 · 1 评论 -
PriorityBlockingQueue 概览
PriorityBlockingQueue 是带 优 先级的无界 阻塞队列,每次出队都返回优先级最高或者 最低的元素。其内部是使用平衡二叉树堆实现的,所以直接遍历队列元素不保证有序。默 认使用对象的 compareTo 方法提供比较规则,如果你需要自定义比较规则则可以自定义 comparators 。PriorityBlockingQueue 内 部有一个数组 queue,用来存放队列元素, ...原创 2019-07-13 11:06:47 · 1178 阅读 · 0 评论 -
JAVA : ReentrantReadWritelock
ReentrantReadWriteLock采用读写分 离的策略,允许多个线程可以同时获取读锁 。架构图读写锁的内部维护了 一个 ReadLock 和一个 WriteLock,它们依赖 Sync 实现具体功能 。 而Sync继承自AQS,并且也提供了公平和非公平的实现。 下面只介绍非公平的读写锁实 现。我们知道 AQS 中只维护了 一 个 state 状态,而 Ree...原创 2019-06-27 18:09:18 · 1148 阅读 · 0 评论 -
JAVA 可重入锁: ReentrantLock
概念ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java关键字synchronized隐式支持重入性, synchronized通过获取自增,释放自减的方式实现重入。与此同时,ReentrantLock还支持公平锁和非公平锁两种方式。那么,要想完完全...原创 2019-06-26 17:17:10 · 1055 阅读 · 0 评论 -
Java CopyOnWriteArrayList 概述
CopyOnWriteArrayList是一个线程 安全的 ArrayList,对其进行的修改操作都是在底层的一个复制的数组(快照)上进行的 ,也就是使用了写时复制策略。 在 CopyOnWriteArrayList 的类图中,每个 CopyOnWriteArrayList 对象里面有一个 array 数组对象用来存放具体元素, ReentrantLock 独占锁对 ...原创 2019-06-26 14:17:30 · 2349 阅读 · 1 评论 -
JDK 8 原子操作类 LongAdder
AtomicLong 通过 CAS 提供了非阻塞的原子性操作,相 比使用阻塞算法的 同步器来说它的性能己经很好了,但是 JDK 开发组并不满足于此 。 使用 AtomicLong 时, 在高并发下大量线程会同时去竞争更新 同→个原子变量,但是由于同时只有一个线程的 CAS 操作会成功,这就造成了大 量 线程竞争失败后,会通过无限循环不断进行自旋尝试CAS 的操作, 而这会白白浪费 CPU 资源。...原创 2019-06-26 11:21:21 · 1864 阅读 · 0 评论 -
在linux系统中查看 缓存行 [ cacheline ] 的大小
linux系统中缓存行 [ cacheline ] 默认值: 64byte为了解决计算机系统中主内存与 CPU 之间运行速度差问题,会在 CPU 与主内存之间 添加一级或者多级高速缓冲存储器( Cache)。这个 Cache 一般是被集成到 CPU 内部的, 所以也叫 CPU Cache,如图所示是两级 Cache 结构。在 Cache 内部是按行存储的,其中每一行...原创 2019-06-25 16:53:07 · 13321 阅读 · 0 评论 -
Java 多线程并发线程基础
进程&线程线程是进程中的一个实体,线程 本身是不会独立存在的 。进程是代码在数据集合上的 一 次运行活动 , 是系统进行资源分配 和调度的基本单位, 线程则是进程的一个执行路径, 一个进程中至少有一个线程,进程中 的多个线程共享进程的资源。操作系统在分配资源时是把资源分配给进程的, 但是 CPU 资源比较特殊, 它是被分 配到线程的 , 因为真正要占用 CPU 运行的是线程 ,...原创 2019-06-25 16:37:40 · 1094 阅读 · 0 评论 -
一张图理解JAVA 多线程创建
Java 中有三种线程创建方式,实现 Runnable接口的 run方法, 继承 Thread类 并重写 run 的方法, 使用 FutureTask方式。原创 2019-06-25 11:46:47 · 1034 阅读 · 0 评论 -
Spark2.3.2源码解析:(多线程)不中断线程 (UninterruptibleThread )
本文讲述,spark中的不中断线程的内容。直接看代码:UninterruptibleThread主要作用是重写 Thread类的interrupt方法,在执行thread.interrupt()方法的时候增加了一个判断uninterruptible(或者说是一个锁,在线程执行完成之后,通过finally进行释放),如果这个值为ture,打断不起作用。默认值false。 un...原创 2019-01-16 13:09:31 · 7431 阅读 · 0 评论 -
ConcurrentLinkedQueue 概览
ConcurrentLinkedQueue 是线程安全的无界非 阻塞队列,其底层数据结 构使用单向链表实现,对于入队和出队操作使用 CAS 来实现线程安全 。ConcurrentLinkedQueue 内部的队列 使用单 向链表方式实现,其中有两个 volatile 类型 的 Node 节点分别用来存放队列的首、尾节点 。从下面的无参构造函数可知,默认头、尾 节点都是指向 ite...原创 2019-07-12 20:34:36 · 972 阅读 · 0 评论 -
LinkedBlockingQueue 和 LinkedBlockingDeque 概览
LinkedBlockingQueue和LinkedBlockingDeque,两个都是队列,只不过前者只能一端出一端入,后者则可以两端同时出入,并且都是结构改变线程安全的队列。其实两个队列从实现思想上比较容易理解,有以下特点:链表结构(动态数组)通过ReentrantLock实现锁利用Condition实现队列的阻塞等待,唤醒LinkedBlockingQueueLin...原创 2019-07-12 20:52:20 · 9134 阅读 · 4 评论 -
抽象同步队列 AQS 三部曲 [ 三 ]
概述AQS 有个内 部类 ConditionObject, 用来结合锁实现线程同步 。 ConditionObject 可以 直接访问 AQS对象内部的变量,比如 state状态值和 AQS 队列。 ConditionObject是条件 变量 , 每 个条件 变量对应 一 个 条 件队列 (单向链表队列),其用来存放调用条件变 量 的 await 方法后被阻塞的线程,如类图所示 , 这个...原创 2019-07-12 16:35:21 · 1087 阅读 · 0 评论 -
抽象同步队列 AQS三部曲 [ 二 ]
图解加锁/解锁 流程图(点击, 放大看)流程概述-------------------------------获取资源-------------------------------当一个线程调用 acquire(int arg)方法获取独占资源时,会首先使用 tryAcquire方 法尝试获取资源, 具体是设置状态变量 state 的值,成功则直接返...原创 2019-07-12 10:41:02 · 1089 阅读 · 0 评论 -
抽象同步队列 AQS三部曲 [ 一 ]
AbstractQueuedSynchronizer 抽象同步队列简称 AQS,它是实现同步器的 基 础组件, 并发包中锁的底层就是使用 AQS 实现的 。AQS是一个FIFO的双向队列,其内部通过节点head和tail记录队 首和队尾元素,队列元素的类型为 Node。其中 Node 中的 thread变量用来存放进入 AQS 队列里面的线程: Node 节点内部的 SHAR...原创 2019-07-12 10:27:52 · 1194 阅读 · 0 评论 -
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor 是一个 可以 在指定一定延迟时间 后或者定时进行 任务调度执行的线程池。...原创 2019-07-14 22:14:56 · 900 阅读 · 0 评论 -
FutureTask 概览
概念FutureTask一个可取消的异步计算,FutureTask 实现了Future的基本方法,提空 start cancel 操作,可以查询计算是否已经完成,并且可以获取计算的结果。结果只可以在计算完成之后获取,get方法会阻塞当计算没有完成的时候,一旦计算已经完成,那么计算就不能再次启动或是取消。一个FutureTask 可以用来包装一个 Callable 或是一个runnable对...原创 2019-07-14 10:08:33 · 523 阅读 · 0 评论 -
ThreadPoolExecutor 概述 [ 二 ]
ThreadPoolExecutor 的实现 实际是一个生产 消费模型, 当用户添加任务到线程池时相当于生产 者生产元素, workers 线程工作集中的线程直接执行任务或者 从任务队列里面获取任务时则相当于消费者消费元素。程池巧妙地使用 一个 Integer类型的原子变量来记录线程池状态和线程池中 的钱程 个数。通过线程池状态来控制任务的执行,每个 Worker线程可以处理多个任务。线程池 ...原创 2019-07-13 17:57:18 · 959 阅读 · 0 评论 -
ThreadPoolExecutor 概述 [ 一 ]
概述线程池主要解决两个问题 :一是当执行大量异步任务时线程池能够提供较好的性能 。 在不使用线程池时,每当需要执行异步任务时直接 new 一个线程来运行,而线程的创建和 销毁是需要开销的。 线程池里面的线程是可复用的,不需要每次执行异步任务时都重新创 建和销毁线程 。二是线程池也提供了 一种资源限制和管理的手段,比如可以限制线程的个数, 动态新增线程等 。 每个 ThreadPoo!E...原创 2019-07-13 17:23:10 · 1064 阅读 · 0 评论 -
JAVA 线程池ThreadPoolExecutor的五种状态
在 线程池成员变量 ctl 是一个 Integer的原子变量,用来记录线程池状态和 线程池中线程个数,类似于 ReentrantReadWriteLock 使用 一个变量来保存两种信息。Integer 类型是 32 位二进制表示,则其中高 3 位用来表示线程池状态,后面 29 位用来记 录线程池线程 个数 。private final AtomicInteger ctl = new At...原创 2019-07-13 16:03:06 · 1891 阅读 · 0 评论 -
DelayQueue 概览
DelayQueue 内部使用 PriorityQueue 存放数据,使用 ReentrantLock 实现 线程同步 。另 外,队列里面的元素要实现 Delayed 接口,由于每个元素都有一个过期时间 , 所以要实现获知当前元素还剩下多少时 间就过期了的接口,由于内部使用优先级队列来实 现,所以要实现元素之间相互比较的接口。类图其中 leader变量的使用基于 Leade...原创 2019-07-13 11:23:15 · 1023 阅读 · 0 评论 -
ArrayBlockingQueue 概览
底层使用数组实现.常量代码: /** The queued items */ final Object[] items; /** items index for next take, poll, peek or remove */ int takeIndex; /** items index for next put, offer, or add */...原创 2019-07-12 21:09:28 · 963 阅读 · 0 评论