每日一练进击大厂「DAY7」并发编程4

每日一练进击大厂「DAY7」并发编程4

文章目录

  • 一、有三个线程T1,T2,T3如何保证顺序执行
  • 二、AQS
  • 三、CountDownLatch
  • 四、CyclicBarrier
  • 五、Semaphore
  • 六、自旋锁
  • 七、偏向锁
  • 八、轻量级锁
  • 九、重量级锁
  • 十、Synchronized升级流程
  • 十一、可重入锁(ReentrantLock)
  • 十二、synchronized和Lock区别
  • 十三、乐观锁
  • 十四、悲观锁
  • 总结

一、有三个线程T1,T2,T3如何保证顺序执行

可以使用线程类中的join方法,在一个线程中启动另一个线程,另外一个线程执行完该线程继续执行。T3的run方法中执行t2.join(),T2的run方法中执行t1.join(),这样就会按照T1,T2,T3的顺序执行了。

二、AQS

AQS是java.util.concurrent包下的工具类,全称是AbstractQueuedSynchronizer抽象队列同步器,AQS是多线程同步器,Lock、CountDownLatch、Semaphore都用到了AQS,从本质上来说AQS提供了两种锁机制,分别是排它锁和共享锁。排它锁:就是存在多线程竞争同一共享资源时,同一时刻只允许一个线程访问该共享资源,也就是多个线程中只能有一个线程获得锁资源,比如Lock中的ReentrantLock重入锁实现就是用到了AQS中的排它锁功能。共享锁:也称为读锁,就是在同一时刻允许多个线程同时获得锁资源,比如CountDownLatch、Semaphore都是用到了AQS中共享锁功能。

三、CountDownLatch

CountDownLatch是基于执行时间的同步类,允许一个或多个线程等待其他线程完成操作,构造方法接收一个int参数作为计数器,如果要等待n个点就传入n,每次调用countDown方法时计数器减1,await方法阻塞当前线程直到计数器变为0,由于countDown方法可用在任何地方,所以n个点既可以是n个线程,也可以是一个线程里的n个执行步骤。

public class CountDownLatchDemo { //主线程等待子线程执行完毕 public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); for (int i = 0; i { try { Thread.sleep(5000); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + “执行了此任务”); countDownLatch.countDown(); }).start(); } countDownLatch.await(); System.out.println(“执行主线程代码”); }}public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { //子线程等主线程计数器变0一起执行 CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 0; i { try { countDownLatch.await(); } catch (Exception e) { } System.out.println(Thread.currentThread().getName() + “执行了此任务”); }).start(); } Thread.sleep(5000); System.out.println(“执行主线程代码”); countDownLatch.countDown(); }}

四、CyclicBarrier

循环屏障是基于同步到达某个点的信号量触发机制,作 是让 组线程到达 个屏障时被阻塞,直到最后 个线程到达屏障才会解除。构造 法中的参数表示拦截线程数量,每个线程调 await 法告诉CyclicBarrier 已到达屏障,然后被阻塞。还 持在构造 法中传 个 Runnable 任务,当线程到达屏障时会优先执 该任务。适 于多线程计算数据,最后合并计算结果的应 场景。CountDownLacth 的计数器只能 次, CyclicBarrier 的计数器可使 reset 法重置,所以CyclicBarrier 能处理更为复杂的业务场景,例如计算错误时可 重置计数器重新计算。

五、Semaphore

信号量 来控制同时访问特定资源的线程数量,通过协调各个线程以保证合理使 公共资源。信号量可以 于流量控制,特别是公共资源有限的应 场景, 如数据库连接。Semaphore 的构造 法参数接收 个 int 值,表示可 的许可数量即最 并发数。使 acquire 法获得 个许可证,使 release 法归还许可,还可以 tryAcquire 尝试获得许可。

六、自旋锁

synchronized是重量级锁,拿到锁必须要阻塞,当量大的时候会一直阻塞唤醒,优化一下,不要让其阻塞,只是告诉有这么个标记,在synchronized的边界做循环,这就是自旋,如果做了多次循环发现还没有获得锁,再阻塞。

七、偏向锁

有一个线程来访问代码块,没有锁的竞争,偏向某个线程,把偏向锁的偏向标记存储为线程的线程id(主要是同一个线程反复抢占锁的场景),只有一个线程,如果线程抢占那么就会升级成轻量级锁,偏向锁默认是关闭的。

八、轻量级锁

有线程竞争,自旋去判断这个对象的锁是否释放,自旋次数(默认根据上一次自旋次数和锁的释放时间来决定),会升级重量级锁

九、重量级锁

线程阻塞等待。

十、Synchronized升级流程

首先synchronized会尝试使用偏向锁的方式去竞争锁资源,如果能够竞争到偏向锁,表示加锁成功直接返回。如果竞争锁失败,说明当前锁已经偏向了其他线程,需要将锁升级到轻量级锁,在轻量级锁状态下,竞争锁的线程根据自适应自旋次数去抢占锁资源。如果在轻量级锁状态下还是没有竞争到锁,就只能升级到重量级锁,在重量级锁状态下,没有竞争到锁的线程就会被阻塞,线程的状态就是Blocked。

十一、可重入锁(ReentrantLock)

在运行的某个函数或者代码,因为抢占资源或者中断等原因导致函数或者代码的运行中断,等待中断程序执行结束后,重新进入这个函数或者代码中运行,并且运行结果不会受到影响,那么这个函数或者代码就是可重入的。ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义。线程A在第一次抢占到锁,在还没有释放之前再次得到锁,这个时候就不需要重新抢占锁,而是增加重入次数,然后锁需要被释放两次才能获得真正的释放。ReentrantLock是一种可重入的排它锁,主要用来解决多线程对共享资源竞争的问题特性:1)支持可重入。2)支持公平和非公平。3)提供了阻塞竞争锁和非阻塞竞争锁的两种方法,分别是lock()和tryLock()。几个非常关键的技术:锁的竞争,ReentrantLock通过互斥变量,使用CAS机制来实现的,没有竞争到锁的线程,使用了AbstractQueuedSynchronized这样一个队列同步器来存储,底层是通过双向链表来实现的,当锁被释放之后,会从AQS队列里的头部唤醒下一个等待锁的线程。公平和非公平的特性,主要体现在竞争锁的时候,是否需要判断AQS队列存在等待中的线程。等待队列里的锁则是公平锁,如果都可以竞争锁,则是非公平锁。锁的重入特性,在AQS里面有一个成员变量来保存当前获得锁的线程,当同一个线程下次再来竞争锁的时候,就不会去走锁竞争的逻辑,而是直接增加重入次数。

十二、synchronized和Lock区别

  • synchronized是关键字,是底层JVM层面实现,Lock是java的juc包下的接口实现。
  • synchronized异常会释放锁,lock必须手动释放锁。
  • synchronized不能响应中断,lock可以响应中断。
  • synchronized可重入,非公平,lock可重入、可公平可非公平。
  • synchronized通过两种方式来控制锁的粒度一种是修饰在方法层面,另一种是修饰在代码块上。Lock锁的粒度是通过它里面提供的lock()和unlock()方法决定的。
  • Lock比synchronized灵活性更高,Lock可以自主抉择什么时候加锁,什么时候释放锁,Lock还提供了非阻塞的竞争锁方法tryLock()方法,这个方法通过返回true/fasle来告诉当前线程是否已经有其他线程正在使用锁。
  • synchronized引入了偏向锁、轻量级锁、重量级锁以及锁升级的方式来优化加锁的性能;Lock则用到了自旋锁的方式来实现性能优化。
  • 十三、乐观锁

    对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将比较替换这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。

    十四、悲观锁

    对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,直接上锁操作资源。


    总结

    择一良人,选一城市,三餐四季,春夏秋冬

    郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
    (0)
    用户投稿
    上一篇 2022年7月9日
    下一篇 2022年7月9日

    相关推荐

    • 海岛奇兵:满防也不见得能抵御对手,那远不如放弃防御只升科技

      海岛奇兵:满防也不见得能抵御对手,那远不如放弃防御只升科技! 在海岛奇兵当中,很多玩家在日常发育当中会感到时间极其漫长,如果将所有的建筑和科技都升级的话,会花费大量的时间,但是在进…

      2022年6月29日
    • 关于Android Fragment 漏洞,你了解多少?

      也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 更多关于Android安全的知识,可前往…

      2022年9月25日
    • 联想ideaPad 2022优势无可比拟,上代旗舰无可奈何沦落白菜价清仓

      联想ideaPad2022虽然拥有15.6英寸的大尺寸,但整机便携性十足,轻了约1.6Kg,薄了17.9mm。同时,15.6英寸微边框全高清屏幕显示效果细腻,雾面防眩光屏幕,即使在…

      2022年6月16日
    • 秃头女大学生自救指南

      大家知道正确的的洗头方法吗? 洗头方法不对或可以导致头发出油快!掉发多!贴头皮!等情况 除此之外洗发水的选择也大有学问! 下面小编带大家了解一下不同功效的洗发水 小编在用的是肌临防…

      2022年7月12日
    • 肥肠怎么洗不臭又干净(肥肠清洗实用方法附详细操作步骤)

      大家好提到猪大肠,相信很多朋友都是又爱又恨,因为大肠的味道是非常臭的,但是把它做好了的话,其味道就会很香。像我就是一个很喜欢吃猪大肠的人,但是想让我自己做的话,我每次都会特别烦,因…

      2022年5月1日
    • 浅析 Java 程序语言的运行机制

      Java 程序语言的运行机制 Java 是一门高级语言,它既包含解释型语言的特征, 也具有编译型语言的特征。因为 Java 应用程序是需要先经过编译,再进行解释两个步骤。 解释型和…

      2022年7月2日
    • 不上门必赔付!?顺丰有三重深意

      事情大家应该都知道了。昨天(9月5日),顺丰突然爆出一个“杀手级”大招—— 2022年9月5日起,顺丰在全国50个主要大中型城市推出“派件不上门,承诺必赔付”服务计划。这50个城市…

      2022年9月9日
    • 面试官:有了解过线程池的工作原理吗?说说看

      面试官: 有了解过线程池的工作原理吗?说说看 前言 目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注 ~ 本节主要带大家从T…

      2022年6月23日
    • justjavac:从辍学到成为Deno核心代码贡献者,我的十年编程生涯

      【CSDN 编者按】大学因学费而辍学,最困难时睡在公园长椅,有远见的母亲让他走上了编程之路,温柔智慧的妻子用爱与信任激励着他秉承初心、奋勇前行。编程十余年,他已在GitHub开源三…

      2022年7月11日
    • 5个错误养生观念

      1、吃素最健康 很多老年人长期坚持吃素,他们觉得吃素会更加健康,更有利于长寿。其实不管是吃素还是吃荤,只要合理搭配能够满足人体日常所需的营养,就是健康的饮食。有些人听信了这种谣言,…

      2022年9月10日

    联系我们

    联系邮箱:admin#wlmqw.com
    工作时间:周一至周五,10:30-18:30,节假日休息