![](https://img-blog.csdnimg.cn/20210809164218837.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Arthur解析系列之并发编程
文章平均质量分 61
由浅入深讲解并发编程面试点相关知识
愿好
科技推动人类物质文明发展,人文推动人类精神文明发展。
展开
-
AQS共享模式之CyclicBarrier
假如公司团建,大家一起做大巴车,在大巴车出发之前,肯定是需要点名的,只有大家都到车上之后,才会发车,然后到了到了目的地之后,肯定是所有人都下车了,司机才能把车开走,这个过程中涉及了2次大家都就位之后,司机才能继续操作,可以证明CyclicBarrier可以循环使用计数器。:CyclicBarrier翻译为循环(屏障/栅栏),当一组线程到达一个屏障(同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续工作。1、【某一个线程需要其余线程执行完之后再执行 (一个等多个)】,原创 2024-04-30 17:31:22 · 94 阅读 · 1 评论 -
死锁概念、产生条件、避免和排查
1、死锁概念:一组互相竞争资源的线程相互等待导致永久堵塞的现象。相对应的有活锁,线程没有阻塞,但一直处于循环状态下,活锁有可能自行解开。2、死锁产生条件:1、互斥,共享资源X和Y只能被一个线程占用;2、占有且等待(请求和保持),线程T1已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X3、不可抢占(不可剥夺),其他线程不能强行抢占线程T1占有的资源4、环路等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源3、如何避免死锁:破环除互斥的其他三个条件之原创 2021-10-29 22:18:12 · 223 阅读 · 0 评论 -
合理设置线程数
1、Amdahl(阿姆达尔)定律概念:描述了线程数与多线程程序相对于单线程程序的提速之间的关系。公式:P:程序中必须串行(即无法并发优化)的部分耗时占程序总耗时的比率。N:为线程数。Smax即理论上最大提速。公式推导思路:设程序单线程版耗时为T(1),多线程版耗时为T(N),P为单线程的耗时比例。则Smax结果为以下:设T(1)为1,则串行耗时为P,可并行部分耗时1-P,通过N个线程并发则,并行部分耗时为(1-P)/N。则T(N)=P+(1-P)/N,则带入图2公式,则图2即原创 2021-08-31 22:20:10 · 1664 阅读 · 0 评论 -
Java实现阻塞队列常用方式对比
1、采用synchronized锁以及wait ()和notify()方法实现缺点:自己使用同步关键字不仅管理混乱,而且容易出错。使用互斥锁和条件变量Condition更简洁。2、采用Condition和Lock锁以及await()和signal()方法实现,即互斥锁和条件变量缺点:使用BlockingQueue可进一步简化代码,不需要编写线程同步资源和唤醒线程的代码。3、采用BlockingQueue实现,源码都是使用重入锁、条件变量来实现BlockingQueue有四个具体的实现类,原创 2021-08-24 15:05:46 · 166 阅读 · 0 评论 -
你了解condition吗
概念: Condition是用于线程控制达到某种条件的方式,condition对象是通过lock.newCondition()创建的,而这个方法实际上是会new出一个ConditionObject对象,该类是AQS(AbstractQueuedSynchronizer)的一个内部类。condition要和lock配合使用的,也就是condition和Lock是绑定在一起的,而lock的实现原理又依赖于AQS。设计lock和condition原因:1、死锁问题synchronized 申请资源原创 2021-08-24 14:57:22 · 190 阅读 · 0 评论 -
AQS共享模式应用countDownLatch时序图
共享资源获取流程:共享资源释放流程:原创 2021-08-24 09:45:24 · 219 阅读 · 0 评论 -
说说ReentrantLock,ReentrantLock底层是AQS,AQS的原理
概念:ReentrantLock(可重入锁):一个线程已经获得了锁,其内部还可以多次申请该锁成功(即不需要再次抢占锁,直接增加重入的次数)。ReentrantLock并没有直接继承AQS类,而是通过内部类来继承AQS类的,这样自己的实现功能,自己用。默认NonfairSync非公平锁。公平锁的实现机理在于每次有线程来抢占锁的时候,都会检查一遍有没有等待队列(FIFO双端队列),相对于非公平锁lock()少了插队部分(即少了CAS尝试将state从0设为1,进而获得锁的过程)。(2次插队)原理图:原创 2021-08-23 15:09:37 · 453 阅读 · 0 评论 -
讲下你对TheadLocal 的理解
概念:ThreadLocal在线程对其进行访问时,会在线程本地创建一个变量副本,对副本进行操作, 从而达到线程间的隔离。而普通的同步机制中,是通过对象加锁来实现多个线程对共享资源的安全访问的。如果你需要在多个线程之间进行通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用ThreadLocal;为什么ThreadLocalMap的entry继承WeakReference<ThreadLocal<?>>,即entry的key是弱引用?Map中的key为原创 2021-08-23 14:47:54 · 101 阅读 · 0 评论 -
引用类型有哪些,分别介绍下?内存泄漏
强引用、软引用、弱引用、幻象引用(虚引用);强引用:普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。软引用(SoftReference):一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象。JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象弱引用(WeakReference):仅仅是提供一种访问在弱引用状态下对象的途径,一旦GC发现了只具有弱引用的对象原创 2021-08-23 14:45:33 · 559 阅读 · 0 评论 -
Synchronized实现原理及锁优化,具体是jdk哪个版本做了什么优化?
1、Synchronized实现原理依赖于锁机制和内存屏障从线程安全的三个特性分别对应做了如下的实现:原子性:锁,其中涉及锁优化(锁升级(偏向锁、轻量级锁、重量级锁(objectMonitor))、锁粗化、锁消除)可见性:加了load屏障和store屏障,释放锁flush数据,加锁会refresh数据有序性:acquire屏障和release屏障,同步代码块内的指令可能重排,但同步代码块内的指令和外面的指令是不会重排的2、synchronized用的锁是存在Java对象头里的(图可不原创 2021-08-11 20:42:22 · 570 阅读 · 0 评论 -
你知道指令重排以及happens-before原则是什么吗?
指令重排:编译器优化后导致指令执行顺序和代码顺序不一致。为了解决多线程的可见性问题,就搞出了happens-before原则,让线程之间遵守这些原则。即前一个操作的结果可以被后续的操作获取。有6个常用原则:程序顺序规则 (as-if-serial语义):排序不能改变程序的执行结果,指令存在依赖关系,是不允许重排序传递性规则:a happens-before b;b happens-before c;则a happens-before cvolatile变量规则:volatile 修饰的变原创 2021-08-11 15:59:15 · 253 阅读 · 0 评论 -
Volatile硬件级分析
1.为了解决处理器与主存之间的速度鸿沟,引入高速缓存,却又导致了缓存一致性问题高速缓存其实就是一组称之为缓存行(cache line)的固定大小的数据块缓存一致性问题:CPU有各自的高速缓存,读取共享变量后操作各自的副本而不可见导致了预期结果和最终结果不一致。2.为了解决缓存一致性问题,引入了总线锁,又导致性能问题,引入了缓存锁,用到了缓存一致性协议如MESI等技术,又导致了处理器等待(写请求阻塞)问题总线锁:类似互斥锁,在通信总线上加锁保证多个CPU访问内存保持互斥特性缓存锁:当CPU原创 2021-08-11 15:14:56 · 598 阅读 · 1 评论 -
谈谈线程中断
为什么需要线程中断?一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果比如会带着自己所持有的锁而永远的休眠,迟迟不归还锁等。 所以你看到Thread.suspend, Thread.stop等方法都被Deprecated了。那么不能直接把一个线程搞挂掉, 但有时候又有必要让它结束某种等待的状态 该怎么办呢?一个比较优雅而安全的做法是:使用等待/通知机制或者给那个线程一个中断信号, 让它自己决定该怎么做。使用场景:子线程sleep后等待的条件提前到来,原创 2021-08-10 23:40:46 · 160 阅读 · 0 评论 -
OS通用线程生命周期和java线程生命周期
1、结论先行:os通用线程生命周期:3种:就绪ready、运行中running、等待/挂起waitingjava线程生命周期:6种:new、runnable、blocked、waiting、timed_waiting、terminated;2、通用线程生命周期:就绪(ready): 表示线程已经被创建,正在等待系统调度分配CPU使用权。运行中(running): 表示线程获得了CPU使用权,正在进行运算等...原创 2021-07-02 16:00:36 · 180 阅读 · 0 评论 -
线程创建的四种方式
java中创建线程的四种方法以及区别Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程,如下所示:1)继承Thread类创建线程2)实现Runnable接口创建线程3)使用Callable和Future创建线程4)使用线程池例如用Executor框架下面让我们分别来看看这四种创建线程的方法。--...原创 2018-03-30 14:34:14 · 183751 阅读 · 14 评论 -
什么是线程和进程、线程安全性问题
概念:线程:CPU调度的一个最小单元;进程:系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。 一个进程可以拥有多个线程线程安全性问题:1、先解释下共享变量:一个变量在多个线程中都有副本即共享变量。2、线程的三个特性:原子性:即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。原子性就像数据库里面的事务一样,他们是一个团队,同生共死有序性:程序执行的顺序按照代码的先后顺序执行可见性:一个线程对共享变量值的修改,能够及时被其他线程看到原创 2021-08-09 16:45:00 · 226 阅读 · 0 评论