25届实习秋招-Java面试-JUC多线程常见知识点

JUC

线程

  • 线程原理:

  • 什么是进程:

    • 特征
  • 什么是线程:

    • 为什么多线程什么时候用会变快,什么用单线程,

    • 进程和线程的对比:

    • 创建线程的方式/方法--看javaNote

      • Thread类(重写哪个,怎么调用,缺陷)
      • runnable(接口,优点) ,与thread的关系
      • callable接口(返回值,怎么包装成线程对象)
        • FutureTask
        • get方法
        • callable和runnable异常信息
      • run和start的区别
    • linux,windows,java查看和杀死进程/线程的方法

      • windows
      • linux
        • Process status --ps
          • 查看线程执行时间呢
          • 如何查看有多少线程。
        • top是一个命令行实用程序,用于监视系统的实时进程和系统性能。
        • 查看java线程栈
    • 线程运行栈帧过程--了解

      • 哪些会引起上下文切换
    • 线程状态-生命周期:

      • 全部由系统控制
      • 状态流程和转化
        • start方法作用,线程怎么唤醒的
        • 没有区分就绪状态和运行状态统一为runnable,没有running
    • 线程方法:

      • join作用
        • 新建 T1、T2、T3 三个线程,如何保证它们按顺序执行?
        • 底层是什么,怎么唤醒
      • 线程暂停的方法
        • sleep和yield,yield会阻塞吗,
        • sleep和wait的区别,会释放对象锁吗
        • 分别什么时候使用?wait用于通信。
          • 为什么sleep方法不需要申请释放锁
      • interrupt,异常处理:
        • 哪些方法会阻塞,打断阻塞线程和正常线程的区别。
        • 其它线程调用interrupt进行中断它会立即中断吗
          • 三个方法的区别
        • 如何终止线程(三个方法)
          • 为什么不建议使用 stop() 停止线程
          • 两阶段优雅终止:怎么做的
        • 打断park线程
          • park是哪里实现的

同步

  • 什么时候会出现线程安全问题:三个条件

  • 线程的同步和异步

    • 同步类似串行执行
  • 临界区和临界资源:

    • 保证临界区的原子性
    • 阻塞式和非阻塞式解决方法:
      • synchronized优缺点,synchronized会发生死锁吗,什么时候死锁(互相等待对方的锁)。synchronized可以保证原子性
  • 同步和互斥的异同

  • 线程安全分析:

    • 什么是线程安全和线程不安全,单核cpu会有线程安全问题吗-有
      • 讲一讲同步机制
      • java怎么处理怎么保证线程安全。
    • 成员变量/静态变量,局部变量是否线程安全
    • 哪些数据结构/类是安全的
      • 这些数据结构的底层,方法组合不安全性
        • 如何对class和bean进行线程安全分析
      • i++是不是线程安全的
      • 怎么设计一个队列,实现线程安全
  • 介绍一下java下的各种锁

    • 如何使用及应用场景
  • synchronized同步锁(对象锁)

    • 同步代码块指加了synchronized的代码块

    • 是什么锁:悲观非公平,可重入重量级

    • synchronized锁在什么情况下会释放

    • synchronized 的使用

    • synchronized的底层原理

      • 总结
      • synchronized存在哪-对象头
      • Monitor-监视器--重量级锁
        • 是什么,存在哪,有什么用,谁提供怎么实现的
        • 工作流程(看javaNote),monitorenter和monitorexit是什么,作用是什么
        • EntryList,Wait Set
        • 说说你对 Java 里 monitor的理解?monitor是操作系统里的概念,你能讲讲它在 Java 里的实现吗?
      • 字节码
      • 异常结合try-catch 机制,确保一定会被解锁
      • happens-before,和synchronized中的体现
    • 锁的升级:

      • 有哪些锁,各自作用适用场景

      • 锁升级的方向,锁升级过程,对synchronized 进行升级。synchronized一定是悲观的吗

      • 偏向锁:

        • 相比轻量级锁的优点
        • MarkWord字段记录什么
        • 导致撤销的三种情况,状态的变换
        • 批量重偏向和批量撤销
      • 轻量级锁:

        • 默认开启偏向锁,偏向-轻量,未开启会直接到轻量锁

        • 操作流程,CAS的作用(硬件原语同步)

          • LockRecord在栈帧中,存锁对象的Markword,,锁对象MarkWord指向LockRecord和LockRecord相互引用
        • CAS上锁失败的两种可能性:

        • 锁膨胀:

          • 如何升级,流程
        • 什么情况下会达到重量级锁

        • 什么情况时候适合用轻量级锁,重量级锁

      • 锁的优化:

        • 自旋锁用在哪-优缺点,自适应自旋锁
        • 锁消除(原理)
        • 锁粗化
  • park unpark

  • wait-notify-作用

    • notify/notifyAll,内部做了什么事情?
      • 和sleep的区别,分别属于什么
      • 怎么获取时间片
      • wait底层原理
  • 活跃性

  • ReentrantLock见同步器部分:

  • 同步模式

内存-JMM

补充看ediary的JVM中的JMM

  • JMM是什么,作用

  • 并发三大特性

    • 缓存一致,什么是缓存一致性协议
  • volatile-不是锁和锁有关 :总结

    • synchronized 和volatile区别

      • 如何保证两个特性
    • 为了解决什么

      • 三个特性中的哪里那两个特性,哪个不能实现
      • 另外两个怎么实现的
    • 底层原理

      • 底层lock和内存屏障的关系
      • 细看下
        • 底层 volatile,对应的属性的access_flag为ACC_VOLATILE,汇编指令中添加上内存屏障指令。调用OrderAccess,不同硬件不同实现,x86用lock实现
      • 可见性lock:如何保证可见性的,为什么有可见性问题。
      • volatile保证有序性
        • 如何禁止指令重排序,为什么指令要重排序
          • 重排序两个原则-简单了解
          • 对象半初始化
        • 内存屏障
    • 用volatile的地方:一个读,多个写。AtomicInteger

无锁

  • CAS

  • Atomic原子类

    • 常见方法,哪两个组合
    • AtomicInteger原子类
      • 原理
      • 常用方法api,自增,加法,乘法。
      • 如何模拟一个api
    • 原子引用,ABA问题
      • 如何解决
    • 对象的属性原子类(volatile)
    • unsafe怎么用
      • 本质还是用了cpu的指令
    • Adder原子累加器,了解下就行
  • 不可变类

    • final,String为什么线程安全。设置/获取final变量的原理
  • ThreadLocal-总结

    • 基本介绍:

      • 为什么要用threadLocal,适用的场景(单线程多线程)
        • 实例是什么类型,放在哪
        • threadLocal包住原来的变量,可以多个threadLocal1,threadLocal2
      • 和synchronized的区别
    • 基本使用:

      • 常用的方法set和get
        • set,获取线程thread对象后,获取到当前thread对象的ThreadLocalMap
        • 一个线程可以有多个ThreadLocal对象,存在每个线程的ThreadLocalMap
    • 底层实现原理:

      • 底层结构
        • JDK8以前,存在什么问题为什么,如何解决

        • JDK8以后呢:

          • Key和value是什么,谁持有
        • 前后对比

      • 成员方法:
        • 怎么保证并发安全,每个线程一个ThreadLocalMap 对象
    • threadLocalMap

      • Thread 类中有维护两个 ThreadLocal.ThreadLocalMap 对象,通过set和get创建
        • ThreadLoalMap是ThreadLocal中的一个静态内部类,类似HashMap
          • Entry内部使用ThreadLocal作为key,使用我们设置的value作为value。 key 为 ThreadLocal 的弱引用,value是强引用
      • 为什么内存泄漏,怎么解决的内存泄漏;
        • 手动调用remove()方法,remove方法了解吗?
          • 为什么虚引用了还要remove:static final
        • 清理方式:了解
    • ThreadLocal跨线程数据共享

    • ThreadLocal和阻塞队列都能做到线程安全,他们的区别是啥

    • ThreadLocal 有一次调用了异步线程,数据能接上吗?如果想要数据能够接上该怎么做?
      

线程池

  • 基本概述:

    • 为什么要使用线程池
    • 优点和缺点:
    • 设计模式:策略模式,享元模式,分工模式
  • 阻塞队列-接口:

    • 基本介绍:
      • 线程池的队列分为哪些?可以使用无界队列吗?
        • 数组有界阻塞队列和链表无界阻塞队列哪个性能好
      • 为什么要设计一个阻塞队列:平衡,复用
        • 为什么不创建临时线程而是先放进阻塞队列
    • 线程池中有哪些常见的阻塞队列实现类
      • 阻塞队列是如何实现延迟的,相关源码
      • 定义的方法:阻塞插入
    • 阻塞队列的线程安全性
      • 如何自定义一个阻塞队列,为什么要锁,await会放弃锁
  • 线程池的操作:

    • 线程池的类,上面的接口

    • 创建方式:

      • 如何获取线程池对象-面向对象和过程
        • Executor
          • ThreadPoolExecutor 需要的参数,核心参数是什么
            • 什么时候会触发拒绝策略。拒绝策略有哪些?
            • 非核心线程销毁
          • 整个流程
            • ThreadPoolExecutor 中提交任务后的执行步骤?
        • Executors-工厂方法
          • 线程池的种类有哪几种
          • 适用于什么场景
      • 提交任务的方法,submit和excute
      • 关闭:两个方法的区别
      • 开发要求:
        • 默认的线程池会出现什么问题
        • 线程池的核心线程数设置为多少合适,io密集型任务和cpu密集型选择线程数 ,为什么这么选?
          • 核心线程和非核心线程的区别
      • 定时执行
    • 异常

      • 处理异常的方式
        • Runnable,Callable
      • 线程池里优雅的捕获异常,而不是依托线程池的能力怎么做
  • 工作原理:

    • ThreadPoolExecutor怎么存状态和数量,ctl
    • 成员属性:
      • 成员变量: allowCoreThreadTimeOut
        • 核心线程可以回收吗,怎么回收流程是什么
    • 成员方法:
      • 运行方法中:keepalivetime怎么工作,源码。
  • 其他:

    • 还知道哪些池化技术

    • 看过线程池源码吗,哪些类比较重要

      • 实现过线程池吗,要注意哪些点
    • 有很多请求打过来,阻塞队列有界满了,拒绝策略造成很多请求超时怎么处理

      • 改策略由线程调用
      • 如果不改参数:

同步器

  • 概念:

    • AbstractQueuedSynchronizer(抽象的队列同步器) 是一种用来构建锁和同步器的框架(类),其他类继承了该类。大部分java.util .concurrent下的同步器由它实现
  • AQS

    • AQS提供了什么功能
      • 共享/独占,FIFO等待队列,公平非公平,可重入,允许中断
    • 核心:
      • 实现者重写:tryAcquire/tryAcquireShared-独占/共享,告诉AQS怎样判断当前同步状态是否成功获取或者是否成功释放
      • AQS底层数据结构以及原理,哪里用到了CAS
        • 同步队列,双向
        • 独占锁和共享锁的实现(一个线程/多个线程可以都成功获得锁)
          • 独占锁获取:
            • tryAcquire用来获得同步状态-是否抢到锁。
            • 实现者调用acquire模板方法,间接调用重写的trayAcquire
            • 失败addWaiter(也用了CAS),acquireQueued()用来排队获取锁(失败park)
              • 为什么双向有head,通过判断前一个是不是head来判断是否可获得锁-按顺序,这里就实现了公平。
            • 释放,可中断,超时略看。
          • 共享锁的实现
          • 看state>0是共享锁
      • AQS如何实现公平锁和非公平锁
      • AQS和Synchronized的区别
    • 如何通过AQS自定义一个锁
      • 静态内部类
        • 例如ReentrantLock的NonfairSync,同步组件实现的是同步语义
        • 继承AQS,要重写哪些方法
          • 比如重写tryAcquire(),状态state的更新也是利用了setState(),getState(),compareAndSetState()。
      • 然后再实现lock接口的方法
        • 可以调用AQS的模板方法,模板方法又用了重写的方法
  • ReentrantLock 的底层

    • Reentrantreadwritelock读写锁
  • ReentrantLock

    • ReentrantLock是Lock核心的一个接口

    • synchronized 和reentrantlock的相同点、不同点

    • 可重入:

    • 什么是可打断

      • 是等待可打断
    • 锁超时:

      • try/finally 获取ReentrantLock 锁,finally超时释放锁
      • 要手动释放锁
    • 公平锁:(默认非公平)

      • ReentrantLock的公平锁和非公平锁优缺点,java里面有机制保证线程不会长时间阻塞吗
      • new ReentrantLock().lock()大概做了什么:底层代码-总结
        • ReentrantLock的底层,和Aqs有关的设计,源代码
    • 条件变量:

      • 多线程条件变量的作用
      • 代码怎么写,怎么通知
    • reentrantlock和sychronized在性能上区别

      • 原本打算取代,优化后差不多
      • 前者只能用在代码块上
    • 使用的四个注意点

  • semaphore

    • 如何控制某个方法允许并发访问线程的数量
    • 信号量可以用来当锁用吗
      • 设置为1实现互斥
      • 信号量当锁是能防止指令重排问题吗,能够保证数据的可见性吗
      • 信号量可以复用,这个是如何实现的?
  • countdownlanch

    • 使用和原理
    • countdownlatch和cyclicbarrier的区别
    • countdownlanch和semaphore 的区别
    • 能复用吗
  • cyclicbarrier

    • parties的作用
  • 对比各自的实现

并发包-线程安全的集合类:

  • 有哪些线程安全的

  • ConcurrentHashMap

    • 看下源码

    • 并发集合

      • hashtable、ConcurrentHashMap 对比:
        • 性能

        • concurrenthashmap的工作流程

      • 并发死链问题
    • 成员方法:--javaGuide源码

      • put怎么并发安全的:
        • 1.7,segment为空用CAS初始化对应segment(HashEntry数组),
          • segment中put,继承了ReentrantLock,自选tryLock( )来获取锁
          • CAS+ReentrantLock
        • 1.8,
          • cas和syn加在哪,桶为空和不为空
            • 已经用了synchronized,为什么还要用CAS呢
      • 扩容是怎么保证线程安全
        • 多个线程操作在进行扩容操作时会有几个线程在处理
          • 1.8有个helpTransfer帮助扩容
      • get方法读操作原理,一定能读到最新的数据吗
    • JDK7原理

      • 分段锁具体底层怎么实现的,分多少段(segment会变吗),每个段里多少个内容
      • 1.8之前ConcurrentHashMap支持多少线程同时操作
      • 扩容segment数量/大小 会变吗
    • 1.8之后的优化

    • 很短的时间内将大量数据插入到ConcurrentHashMap

  • CopyOnWriteArrayList

异步模式

  • Future接口和FutureTask类:

    • 总结
      • FutureTask实现了那两个接口,可以包装成线程start调用,也可以用线程池
      • 底层
      • future 是任何时候都可以取到数据吗
  • CompletableFuture

    • 如何实现异步非阻塞调用
    • 用线程池了吗
    • thenApply 方法,是在主线程还是在子线程执行的
    • 使用过程有什么注意的

设计模式

  • 用了哪些设计模式

  • 项目哪里用了多线程, 见ppt

    • java多线程使用过哪些类或者工具

    • 死锁产生的条件,如何用命令查看死锁,见ppt

    • 线程a调用线程b线程a是什么状态,如果没有数据传输呢

  • 子线程出现异常是否影响主线程


__EOF__

本文作者userName
本文链接https://www.cnblogs.com/Blunt-Raz0r/p/17704191.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Blunt-Razor  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示