![](https://img-blog.csdnimg.cn/20201014180756738.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
多线程高级
一如既往的坚持
这个作者很懒,什么都没留下…
展开
-
ReentrantLock源码
默认是非公平,可以通过构造函数控制公平和非公平 public ReentrantLock() { sync = new NonfairSync(); } /** * Creates an instance of {@code ReentrantLock} with the * given fairness policy. * * @param fair {@code true} if this lock should use原创 2020-12-29 14:29:12 · 143 阅读 · 0 评论 -
Unsafe类API介绍
Unsafe类通过JNI的方式访问本地的C++实现库从而使java具有了直接操作内存空间的能力,Unsafe提供了硬件级别的原子性操作objectFieldOffset()方法用于获取某个字段相对Java对象的“起始地址”的偏移量unsafe.compareAndSwapInt这个方法,这个方法有四个参数,其中第一个参数为需要改变的对象,第二个为偏移量(即之前求出来的valueOffset的值),第三个参数为期待的值,第四个为更新后的值。public class UnsafeTest1 { .原创 2020-12-16 15:20:44 · 305 阅读 · 1 评论 -
内存屏障
JMM内存模型线程A与线程B之间的通信,必须经历两步1)线程A把本地内存A中更新过的共享变量刷新到主内存去2)线程B到主内存中去读取线程A之前已更新过的共享变量重排序1)编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。2)指令级并行的重排序。现代处理起采用了指令级并行技术静多条指令重叠执行。不过不存在数据依赖性,处理起可以改变语句对应机器指令的执行顺序3)内存系统的重排序。由于处理器使用缓存和读/写缓存区,这使得加载和存储操作看上去可能是乱序执行。1)原创 2020-11-01 18:35:38 · 177 阅读 · 0 评论 -
锁升级简单介绍
为什么要引入偏向锁?因为经过HotSpot的作者大量的研究发现,大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。为什么要引入轻量级锁?轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。轻量级锁什么时候升级为重.原创 2020-12-14 14:32:52 · 2400 阅读 · 0 评论 -
Executor框架的介绍
executor框架组成任务: 包括被执行任务需要实现的接口:runnable和callable任务的执行: 包括任务执行机制的核心接口Executor,以及继承自ExecutorExecutorService接口,他有两个关键实现类:ThreadPoolExecutor和ScheduledThreadPoolExector异步计算的结果:包括接口Future和它的实现FutureTask类Executor是Executor框架的基础,他将任务的提交与执行分离开ThreadPoolExecuto原创 2020-10-22 18:17:45 · 932 阅读 · 0 评论 -
线程池的介绍
线程池的好处1.重复利用已创建的线程降低线程创建和销毁造成的消耗2.当任务到达,可以不需要创建线程就立即执行3.提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程可以进行统一分配,调优和监控线程池的实现原理当向线程池提交一个任务之后,线程池的处理流程如下1.线程池判断核心线程池里的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务。如果是核心线程里的线程都在执行任务,则进入下一个流程2.线程池判断工作队列是否已经满。如果工作原创 2020-10-21 22:32:25 · 71 阅读 · 1 评论 -
多线程学习笔记-ReentrantLock
ReentrantLock的几个重要方法:lock():获得锁,如果锁被占用则等待。lockInterruptibly():获得锁,但优先响应中断。tryLock():尝试获得锁,如果成功,则返回true;失败返回false。此方法不等待,立即返回。unlock():释放锁。 private final static Lock lock = new ReentrantLock(); public static void main(String[] args) throws Interr原创 2020-09-01 21:44:26 · 142 阅读 · 0 评论 -
线程学习笔记-Semaphore
Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。很多年以来,我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是控制流量的红绿灯,比如XX马路要限制流量,只允许同时有一百辆车在这条路上行使,其他的都必须在路口等待,所以前一百辆车会看到绿灯,可以开进这条马路,后面的车会看到红灯,不能驶入XX马路,但是如果前一百辆中有五辆车已经离开了XX马路,那么后面就允许有5辆车驶入马路,这个例子里说的车就是线程,驶入马路就表示线程在...原创 2020-08-31 22:33:45 · 114 阅读 · 0 评论 -
线程学习笔记-Exchanger
Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程(成对出现)可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交...原创 2020-08-30 16:28:44 · 103 阅读 · 0 评论 -
多线程学习笔记-CyclicBarrier
1、CyclicBarrier的简单概述现实生活中我们经常会遇到这样的情景,在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子,旅游时要等全部人都到齐了才出发,比赛时要等运动员都上场后才开始。在JUC包中为我们提供了一个同步工具类能够很好的模拟这类场景,它就是CyclicBarrier类。利用CyclicBarrier类可以实现一组线程相互等待,当所有线程都到达某个屏障点后再进行后续的操作。下图演示了这一过程。在CyclicBarrier类的内部有一个计数器,每个线程在原创 2020-08-30 15:36:24 · 167 阅读 · 0 评论 -
多线程学习笔记-CountDownLatch
CountDownLatch介绍CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下CountDownLatch原理CountDownLatch是通过一个计数器来实现的,计数器的初始化值为线程的数量原创 2020-08-26 22:12:52 · 161 阅读 · 0 评论 -
线程学习笔记-AtomicStampReference
CAS引发的ABA问题AtomicStampReference可以解决ABA问题 //当前值 final T reference; //版本戳 final int stamp; public boolean compareAndSet(V expectedReference, V newReference, int expectedS原创 2020-08-25 20:54:50 · 638 阅读 · 0 评论 -
线程学习笔记-AtomicInteger类
AtomicIntege解决以下三个问题可见性有序性原子性AtomicIntege底层使用的是CAS,I=0;两个线程分别做I=I++;第一个线程获取到i=1,第二个线程i=1第二个线程执行完i+1;compare比较相等变为2第一个线程比较current=1和value=2进行比较,发现不相等,继续循环,此时current=2和value=2进行比较,更新值为3compareAndSet使用的是cpu级别的加锁CAS代码for(;;){ //获取当前值 int current原创 2020-08-23 22:23:30 · 145 阅读 · 0 评论