大厂高频面试题复习JAVA学习笔记-JUC多线程及高并发(下)

本文详细探讨了Java并发中的关键概念,如阻塞队列、synchronized与lock的区别,线程池的使用、ThreadPoolExecutor原理、线程池参数设置,以及死锁的编码分析。
摘要由CSDN通过智能技术生成

目录

 7 阻塞队列知道吗?

概念​编辑

synchronized和lock的区别

 虚假唤醒情况

​编辑​编辑

8 线程池用过吗?ThreadPoolExecutor谈谈你的理解?

Callable接口

 线程池

Executors工具类

线程池底层原理 

线程池七大参数

七大参数 底层原理

9 线程池用过吗?生产上你如何设置合理参数

线程池拒绝策略

不要用Executors创建线程池!!

四种拒绝策略

合理线程数怎么设置

10 死锁编码及定位分析

概念

写一个死锁 

 排错

11 总结


上半部分: 

大厂高频面试题复习JAVA学习笔记-JUC多线程及高并发(上)-CSDN博客

  •  7 阻塞队列知道吗?

  • 概念

  • 种类:

synchronized和lock的区别

  1. synchronized是jvm的关键字,lock是一个接口
  2. monitorenter(底层是通过monitor对象来完成,其史wait/notify等方法也依赖于monitor对象只有在同步块或方法中才能源wait/notify等方法
  3. Lock是具体类(java.util.concurrent.locks.Lock)是api层面的锁
  • 锁释放
  1. synchronized 不需要用户去手动释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用
  2. ReentrantLock则需要用户去手动释放锁若没有主动释放锁,就有可能导致出现死锁现象。需要lock()和unlock()方法配合try/finally语句块来完成。
  •  等待是否可中断
  1. synchronized不可中断,除非抛出异常或者正常运行完成
  2. ReentrantLock 可中断,1.设置超时方法 tryLock(long timeout, Timeunit unit)
  3. lockInterruptibly()放代码块中,调用interrupt()方法可中断
  •  加锁是否公平
  1. synchronized非公平锁
  2. ReentrantLock两者都可以,默认非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁
  • 锁绑定多个条件condition
  1. synchronized没有
  2. ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程

  • 此时就要用lock实现:

线程类:

资源类:

 虚假唤醒情况

不要用if来判断,必须用while:

知识点结合版代码案例:

代码太多了暂时还没有复现,原作视频,最好自己实现一下,有助加深理解,44_线程通信之生产者消费者阻塞队列版_哔哩哔哩_bilibili

  • 8 线程池用过吗?ThreadPoolExecutor谈谈你的理解?

Callable接口

只有runnable有些情况不适用,在并发异步的情况下出现了callable,

 线程池

优势:

架构:

Executors工具类

只要是池子,使用完必须关闭!!!

  • Executors.newFixedThreadPool(int)

一池固定数线程

可以submit,也可以execute:

  • Executors.newSingleThreadExecutor()

一池单线程

  • Executors.newCachedThreadPool()

一池多线程

去掉时间停顿:

线程池底层原理 

底层都是new了ThreadPoolExecute,都是用阻塞队列实现

选型:

  1. Executors.newFixedThreadPool(int)执行长期的任务,性能好很多
  2. Executors.newSingleThreadExecutor()-一个任务一个任务执行的场景
  3. Executors.newCachedThreadPool()适用:执行很多短期异步的小程序或者负载较轻的服务

线程池七大参数

  1. corePoolsize:线程池中的常驻核心线程数
  2. maximumPoolsize:线程池能够容纳同时执行的最大线程数,此值必须>=1
  3. keepAliveTime:多余的空闲线程的存活时间。当前线程池数量超过corePoolsize时,当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁直到只剩下corePoolsize个线程为止
  4. unit:keepAliveTime的单位。
  5. workqueue:任务队列,被提交但尚未被执行的任务。
  6. threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的!
  7. handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数时所选策略
  • 案例分析:

线程池就像银行,阻塞队列就是窗口,队列容量就是剩余窗口数量,第一个参数就是今日值班的窗口数,最大数量就是最大可值班窗口数,现在12任务来,分别占两条线程执行,345停在阻塞队列等待执行,此时突然来了678,

678是后来任务,此时阻塞队列满,就需要通知另外三个窗口线程赶紧来加班,会直接抢占加班窗口

keepalivetime,当空闲时间达到阈值,会自动销毁多余线程,既关闭后面三个服务窗口,从maximumPoolsize到corepoorsize:

七大参数 底层原理

 底层原理

处理流程:

  • 1.在创建了线程池后,等待提交过来的任务请求,
  • 2.当调用 execute()方法添加一个请求任务时,线程池会做如下判断:

2.1 如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务;
2.2 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列

2.3 如果这时候队列满了且正在运行的线程数量还小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务

2.4 如果队列满了且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。

  • 3.当一个线程完成任务时,它会从队列中取下一个任务来执行。
  • 4.当一个线程无事可做超过一定的时间(keepAliveTime)时,线程池会判断:

如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。
所以线程池的所有任务完成后它最终会收缩到 corePoolsize 的大小。

  • 9 线程池用过吗?生产上你如何设置合理参数

线程池拒绝策略

既线程池第七个参数:

  1. AbortPolicy(默认):  直接抛出 RejectedExecutionException异常阻止系统正常运行。
  2. CalerRunsPolicy:  “调用者运行",一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者。
  3. DiscardoldestPolicy:  抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。
  4. DiscardPolicy:  直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案。

不要用Executors创建线程池!!

executors中的三个线程池 ,面试官会问工作中用哪个(超级大坑!!!!),回答是一个都不用,原因可以参考阿里开发手册:

四种拒绝策略

当循环8次,可以运行,但是加到9个,直接报错(默认AbortPolicy)

  • 默认AbortPolicy

  • CalerRunsPolicy

  •  DiscardPolicy

合理线程数怎么设置

先调用以下方法,看本公司用的服务器cpu是几核的

实际情况分为IO密集型和CPU密集型:

  • 10 死锁编码及定位分析

概念

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。

写一个死锁 

线程操作资源类:

结果:

注意start并不是按顺序来的!!!!

 排错

1、在终端通过jps命令查看进程编号

2、jstak查看进程:

11 总结

也没什么好总结的,所有知识点列个目录吧:

0 JUC基础概念

 wait/sleep的区别

并发与并行的区别

线程的六个状态

JUC结构 ​编辑

1 请谈谈你对volatile的理解

JMM(java内存模型)

可见性    

不保证原子性

 有序性​编辑

指令重排

哪些地方用到volatile:

双端检查机制DLC

2 CAS你知道吗?

3 原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗?

 ABA问题:

原子引用

4 我们知道ArrayList是线程不安全,请编码写一个不安全的案例并给出解决方案。

 list​编辑

set

map

参数传递​编辑

5 公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁

公平锁和非公平锁

可重用锁(递归锁)

独占锁(写锁)、共享锁(读锁)

自旋锁

6 CountDownLatch/cyclicBarrier/semaphore使用过吗?

CountDownLatch

 自定义枚举类 

CyclicBarrier

Srmaphore

7 阻塞队列知道吗?

概念​编辑

synchronized和lock的区别

 虚假唤醒情况

​编辑​编辑

8 线程池用过吗?ThreadPoolExecutor谈谈你的理解?

Callable接口

 线程池

Executors工具类

线程池底层原理 

线程池七大参数

七大参数 底层原理

9 线程池用过吗?生产上你如何设置合理参数

线程池拒绝策略

不要用Executors创建线程池!!

四种拒绝策略

合理线程数怎么设置

10 死锁编码及定位分析

概念

写一个死锁 

 排错

11 总结

整个JUC大概知识到此完结,因为没有自己编码实现Demo,使用都用贴图的方式展示具体代码,截图均来自尚硅谷教学视频,个人总结笔记用于自己复习记录(所以没有认真做笔记可能别人看起来会很费劲hhhh),但也分享给大家参考参考;

原视频55_死锁编码及定位分析_哔哩哔哩_bilibili(讲的挺好的,推荐大家有时间可以去看完课程,毕竟别人的笔记只有别人自己才能百分百吸收,自己想要最大化汲取知识得要写出自己的笔记效果才好,加油!)

  • 31
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值