并发编程
文章平均质量分 94
Fisher3652
这个作者很懒,什么都没留下…
展开
-
CompletableFuture 使用教程
CompletableFuture实现了CompletionStage接口和Future接口,CompletionStage是对Future的一个扩展,增加了异步回调、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。Future没有提供通知机制,Future是否执行完任务需要通过轮询isDone这个方法查询执行结果或者调用get()方法阻塞任务执行,CompletionStage解决了该问题,前一个任务执行成功后可以自动触发下一个任务的执行,中间无需等待。原创 2022-11-29 17:12:21 · 947 阅读 · 0 评论 -
ConcurrentHashMap
目录为什么要使用 ConcurrentHashMapHashMap死循环分析 ( jdk 1.7 )ConcurrentHashMap1. 在 1.7 下的实现2. 在 1.8 下的实现HashTableHashMap 和 HashTable 有什么区别?Java 中的另一个线程安全的与 HashMap 极其类似的类是什么?同样是线程安全,它与 HashTable 在线程同步上有什么不同?HashMap & ConcurrentHashMap 的区别?为什么 ConcurrentHashMap 比原创 2020-10-24 20:01:24 · 312 阅读 · 0 评论 -
并发编程:java内存模型
JMM1. 关于CPU 内存2. 并发编程会遇到的问题2.1 原子性2.2 可见性2.3 有序性3. java内存模型1. 关于CPU 内存CPU、内存、I/O 设备都在不断迭代,有一个核心矛盾是这三者的速度差异。CPU 和内存的速度差异可以简单地认为:CPU快于内存快于 I/O 设备,程序里大部分语句都要访问内存,有些还要访问 I/O,所以程序整体的性能取决于最慢的操作——读写 I/O 设备,也就是说单方面提高 CPU 性能是无效的。为了合理利用 CPU 的高性能,平衡这三者的速度差异,计算机体系结原创 2020-10-13 09:46:27 · 191 阅读 · 2 评论 -
并发编程:线程池ExecutorService
线程池ThreadPoolExecutor1. 线程池状态2. ThreadPoolExecutor构造方法3. 工作方式4. 代码示例5. 超时演示newFixedThreadPoolThreadPoolExecutor1. 线程池状态ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量runState is stored in the high-order bits|状态 | value| 说明||–|--|–|| RUN原创 2020-09-25 17:15:56 · 335 阅读 · 0 评论 -
并发编程:CyclicBarrier
CyclicBarrier1. CyclicBarrier2. 示例代码1. CyclicBarrier重复栅栏(CountDownLatch),语法和CountDownLatch差不多;使用await(),计算器不为0就-1。和CountDownLatch区别是可以重复执行,而且构造方法可以直接提供一个阻塞的线程,等待计数器为0的时候再执行。基本语法//初始化一个cyclicBarrier 计数器为2CyclicBarrier cyclicBarrier = new CyclicBarr原创 2020-09-24 17:38:22 · 90 阅读 · 0 评论 -
并发编程:CountDownLatch
CountDownLatch1. CountDownLatch2. 代码示例2.1 单机版2.2 配合线程池ExecutorService1. CountDownLatch倒计时锁;某个线程x当倒计时为0的时候才执行;倒计时其实就是一个int类型的变量,在初始化CountDownLatch的时候会给他一个初始值;在多线程工作的时候,使用await()阻塞线程,通过countDown()方法来对计数器-1;当等于0的时候线程则会解除阻塞运行。基本语法//初始化对象,给一个初始值CountDow原创 2020-09-24 16:52:03 · 145 阅读 · 0 评论 -
并发编程:semaphore
samephore1. samephore2. 创建一个测试类SemaphoreTest3. 查看打印结果4. 加锁实现分析1. samephore可以限制对资源访问的线程数量的上限基本语法//设置线程的上限 3Semaphore semaphore = new Semaphore(3);//获取一个许可 - 1semaphore.acquire();//释放 + 1semaphore.release();2. 创建一个测试类SemaphoreTestpackage org.e原创 2020-09-24 15:27:00 · 185 阅读 · 0 评论 -
并发编程:StampedLock
StampedLock1. StampedLock2. 创建一个数据容器DataContainer3. 创建测试类StampedLockTest4. 查看打印1. StampedLockReentrantReadWriteLock 的性能已经很好了但是他底层还是需要进行一系列的cas操作去加锁;StampedLock如果是读锁上锁是没有这种cas操作的,性能比ReentrantReadWriteLock 更好StampedLock控制锁有三种模式(写,悲观读,乐观读)乐观读锁,即读获取锁的时候,原创 2020-09-24 11:11:05 · 147 阅读 · 0 评论 -
并发编程:ReentrantLock读写锁
读写锁1. 写锁加锁流程1. 写锁加锁流程代码示例写锁源码结论:加锁成功1、锁没有被人持有2、锁是重入其他情况都会加锁失败protected final boolean tryAcquire(int acquires) { //1. 获取当前线程 Thread current = Thread.currentThread(); //2. 获取当前锁的状态(0:锁没有被人持有;1:锁已经被人持有;2:重入) int c = getState();原创 2020-09-23 16:13:27 · 266 阅读 · 0 评论 -
并发编程:ReentrantLock的加锁和解锁过程
ReentrantLock1. 和Aqs的关系2. 非公平锁加锁流程1. 和Aqs的关系2. 非公平锁加锁流程第一个线程t1,第一次加锁,没有加锁之前 aqs(NonfairSync)的状态2. t1加锁成功后3. 第二个线程t2尝试加锁,如果加锁成功4. t2加锁失败,会创建队列t == null队列还没有创建;compareAndSetHead(new Node())创建一个Thread=null的head;node.prev = t; t2节点的prev指向head;原创 2020-09-21 16:16:17 · 546 阅读 · 0 评论 -
并发编程:AQS
AQS1. 定义2. 功能3. 自定义实现AQS框架3.1 继承AQS 实现其主要方法3.2 实现Lock接口实现加锁解锁1. 定义1、全称是 AbstractQueuedSynchronizer2、阻塞式锁和相关的同步器工具的框架;3、AQS用一个变量(volatile state) 属性来表示锁的状态,子类去维护这个状态4、getState、compareAndSetState cas改变这个变量5、独占模式是只有一个线程能够访问资源6、而共享模式可以允许多个线程访问资源(读写锁)7原创 2020-09-15 16:11:20 · 165 阅读 · 0 评论 -
并发编程:ReentrantLock应用
ReentrantLock1. 特点2. 重入3. 可打断4. 超时5. 多条件1. 特点可打断,可重入可以设置超时时间可以设置为公平锁支持多个条件变量支持读写锁基本语法reentrantLock.lock();try { //业务代码} finally { reentrantLock.unlock();}2. 重入package org.example;import lombok.extern.slf4j.Slf4j;import java.ut原创 2020-09-15 12:20:25 · 312 阅读 · 0 评论 -
并发编程:死锁
1. 死锁如果线程需要获取多把锁那么就很可能会发现死锁;t1线程获取锁x时,又尝试获取锁y;同时t2线程获取锁y时,又尝试获取锁x;t1要获取t2已经持有的锁y,t2又要获取t1已经持有的锁x,此时将出现互相等待的情况。2. 代码示例package org.example;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.TimeUnit;@Slf4jpublic class DeadLock { s原创 2020-09-15 09:48:18 · 111 阅读 · 0 评论 -
并发编程:wait、notify
目录1. 关于wait notify2. wait和sleep的区别3. 代码示例1. 关于wait notify持有锁的线程发现条件不满足,调用 wait,即可进入 WaitSet 变为 WAITING 状态;BLOCKED 和 WAITING 的线程都处于阻塞状态,不占用 CPU 时间片;BLOCKED 线程会在 持有锁的线程释放锁时唤醒;WAITING 线程会在 持有锁的线程调用 notify 或 notifyAll 时唤醒,但唤醒后并不意味者立刻获得锁仍需进入EntryList 重新竞原创 2020-09-14 17:12:32 · 162 阅读 · 0 评论 -
并发编程:批量重偏向、批量撤销
目录1. 批量重偏向2. 批量撤销1. 批量重偏向如果对象虽然被多个线程访问,但没有竞争,这时偏向了线程 T1 的对象仍有机会重新偏向 T2,重偏向会重置对象的 Thread ID;当撤销偏向锁达到阈值 20 次后,jvm 会这样觉得,我是不是偏向错了呢,于是会在给这些对象加锁时重新偏向至t2。因为前19次是轻量,释放之后为无锁不可偏向,但是20次后面的是偏向t2,释放之后依然是偏向t2。package org.example;import lombok.extern.slf4j.Slf4j;原创 2020-09-14 15:30:12 · 3344 阅读 · 6 评论 -
并发编程:synchronized
synchronized1. 同步代码块2. 反编译3. 偏向锁(A线程来了)4. 轻量锁(B线程来了)5. 重量锁(C线程来了)1. 同步代码块package org.example.test;import org.example.entity.A;public class SynchronizedTest { public static void main(String[] args) { A a = new A(); int i = 0;原创 2020-09-03 00:07:15 · 202 阅读 · 0 评论 -
并发编程:ReentrantLock公平锁非公平锁
公平锁非公平锁1. 公平锁2. 非公平锁3. 队列排序1. 公平锁第一次加锁的时候,他不会去尝试加锁,他会去看一下我前面有没有人排队;如果有人排队,则进入队列(并不等于排队),然后还不死心,再次看一下我有没有拿锁的资格(前面那个人是否为head);如果有资格(前面那个人刚好为head)则继续拿锁,成功则执行同步块;失败则park(排队)。2. 非公平锁首先在lock方法调用加锁的时候就会去抢锁(公平锁调用lock不会上来就拿锁);如果锁没有被人持有,就会去直接加锁(不会判断是否有人排队)原创 2020-09-01 20:26:17 · 163 阅读 · 0 评论 -
并发编程:锁
锁1. 操作系统有哪些方法实现同步2. synchronized是不是自旋锁3. 互斥量4. 重量锁1. 操作系统有哪些方法实现同步互斥量phread_mutex_t(互斥锁),发生竞争时,如果拿不到锁则睡眠自旋锁pthread_spin_t,如果拿不到锁则空转信号量用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。2. synchro原创 2020-08-29 21:55:42 · 131 阅读 · 0 评论 -
并发编程:Java线程的本质
线程1. 创建一个线程类1.1 点击start方法2. linux的线程控制原语2.1 centos安装man手册2.2 查看pthread_create函数定义3. 结论1. 创建一个线程类可以正常运行1.1 点击start方法start方法内有一个start0方法,而且start0方法是一个native本地方法。是通过JNI调用的系统方法,这个start0方法对应的系统创建线程的方法是pthread_create。2. linux的线程控制原语2.1 centos安装man手册原创 2020-08-29 19:53:14 · 321 阅读 · 0 评论 -
并发编程:Java对象头的信息分析
对象头信息分析1. 对象的内存分布1.1 创建一个maven工程1.2 创建一个空的实体类A1.3 创建对象分析测试类HeadTest1.4 查看打印1.5 为对象A添加一个整数型变量1.6 查看打印1.7 结论2. 对象头的规范3. HashCode4. 锁的状态4.1 无锁不可偏向(有hashcode,001)4.2 无锁可偏向(无hashcode,101),但是没有偏向(因为没加锁)4.3 偏向锁已经偏向(101)4.4 轻量锁(00)4.5 重量锁(10)5. 结论1. 对象的内存分布在 H原创 2020-08-29 17:44:09 · 344 阅读 · 0 评论 -
并发编程:如何实现一个简单的锁
目录1. 创建一个maven工程2. 创建加锁解锁类CASlock3. 创建测试类LockTest4. 在使用锁的情况下,查看打印结果5. 在不使用锁的情况下,查看打印结果1. 创建一个maven工程2. 创建加锁解锁类CASlockpackage org.example.util;import sun.misc.Unsafe;import java.lang.reflect.Field;public class CASlock { //标识,1:是否有线程在同步代码块,2:是否原创 2020-08-29 10:44:06 · 304 阅读 · 0 评论