Java---JUC并发篇(多线程详细版)

Java---多线程

  • 1. 并发基础(线程篇)
    • 1.1 java线程状态及线程状态之间的转化
    • 1.2 操作系统层面有5种状态
  • 2. 线程池的核心参数(7个核心参数)
    • 2.1 线程池参数介绍
    • 2.2 代码实现
    • 2.3 handler 4种拒绝策略
  • 3. sleep与wait方法对比
    • 3.1 异同点
    • 3.2 代码展示
  • 4. lock锁与synchronized锁区别
    • 4.1 异同点
    • 4.2 代码实现
  • 5. volatile 能否保证线程安全
    • 5.1 什么是线程安全
    • 5.2 代码展示
      • 5.2.1 原子性
      • 5.2.2 可见性
      • 5.2.3 有序性
  • 6. Java中的悲观锁与乐观锁
    • 6.1 悲观锁与乐观锁区别
    • 6.2 代码实现
    • 6.2.1 CAS概念:
    • 6.2.2 悲观锁与乐观锁代码实现共享变量线程安全
  • 7. Hashtable 与 ConcurrentHashMap
    • 7.1 Hashtable 与 ConcurrentHashMap概念区别
    • 7.2 ConcurrentHashMap原理细节
  • 8. ThreadLocal
    • 8.1 谈一谈对ThreadLocal的理解
    • 8.2 线程间隔离 与 线程内共享

1. 并发基础(线程篇)

1.1 java线程状态及线程状态之间的转化

Java线程分成六种状态
Java---JUC并发篇(多线程详细版)_第1张图片
new(新建)—runnable(可运行)—terminated(终结)—blocked(阻塞)—waiting(等待)—timed_waiting(有时限等待)

1.2 操作系统层面有5种状态

Java---JUC并发篇(多线程详细版)_第2张图片
注:Java中的runnable涵盖就绪、运行、阻塞I/O.

2. 线程池的核心参数(7个核心参数)

Java中的线程池及其实现类ThreadPoolExecutor
Java---JUC并发篇(多线程详细版)_第3张图片

2.1 线程池参数介绍

Java---JUC并发篇(多线程详细版)_第4张图片

2.2 代码实现

Java---JUC并发篇(多线程详细版)_第5张图片

2.3 handler 4种拒绝策略

  1. AbortPolicy()—抛出异常
  2. CallerRunsPolicy() — 由main主线程运行,调用者自己执行
  3. DiscardPolicy() — 直接丢弃掉
  4. DiscardOldestPolicy() — 等待最久的线程丢弃掉,新submit来的线程留下来

3. sleep与wait方法对比

3.1 异同点

Java---JUC并发篇(多线程详细版)_第6张图片

3.2 代码展示

  1. wait 要和Lock 配合使用,直接用对象调用wait方法会报错。
    Java---JUC并发篇(多线程详细版)_第7张图片
  2. 获得对象锁,就不会报错了。
    Java---JUC并发篇(多线程详细版)_第8张图片
  3. t1 线程调用wait方法 会释放锁,主线程得到锁。
    Java---JUC并发篇(多线程详细版)_第9张图片
  4. sleep 在synchornized里面 不会释放锁。
    Java---JUC并发篇(多线程详细版)_第10张图片
  5. t1 线程调用interrupt() 可中断sleep和wait方法,提前唤醒t1线程
    Java---JUC并发篇(多线程详细版)_第11张图片

4. lock锁与synchronized锁区别

4.1 异同点

两者都具备基本的互斥、同步、可重入锁(加多道锁)功能。Synchornized 用wait 和notify 实现同步,Lock用await和signal实现同步。
Java---JUC并发篇(多线程详细版)_第12张图片

4.2 代码实现

  1. blocked queue 一个双向链表, 使用lock时,需要手动unlock.
    链接: lock_阻塞演示.
  2. 公平锁与非公平锁
    Java---JUC并发篇(多线程详细版)_第13张图片
  3. lock_条件变量
    Condition类: await阻塞放在waiting queue,signal唤醒到blocked queue 阻塞队列
    Java---JUC并发篇(多线程详细版)_第14张图片
    Java---JUC并发篇(多线程详细版)_第15张图片

5. volatile 能否保证线程安全

5.1 什么是线程安全

Java---JUC并发篇(多线程详细版)_第16张图片

5.2 代码展示

5.2.1 原子性

Java---JUC并发篇(多线程详细版)_第17张图片
虽然运行结果是10,当运行很多次 可能会出错。
balance -= 5; 对应Jvm中有多条指令,若两者(多线程)指令交错,会导致出错,如下所示:
Java---JUC并发篇(多线程详细版)_第18张图片

5.2.2 可见性

下面案例是不可见性(无限循环)
Java---JUC并发篇(多线程详细版)_第19张图片
JIT即时编译器会优化热点代码。
正确修改: static volatile boolean stop = false; 解决可见性问题

5.2.3 有序性

大量的压测试验。
Java---JUC并发篇(多线程详细版)_第20张图片
voliate加的x,y位置不一样效果也不一样。
voliate在内存屏障来实现有序性 下面显示正确案例:(voliate变量 要加在最后写的变量上,最先读的变量上,这样才能起到屏障地作用)
Java---JUC并发篇(多线程详细版)_第21张图片

6. Java中的悲观锁与乐观锁

6.1 悲观锁与乐观锁区别

上下文切换的概念:运行–阻塞:记录状态与恢复状态
Java---JUC并发篇(多线程详细版)_第22张图片

6.2 代码实现

6.2.1 CAS概念:

链接: 什么是java中的CAS?.
用cas(cas提供原子性)共享变量时,需要voliate修饰。(voliate保证可见性),一般要配合使用。
乐观锁展示:(比较并交换)
Java---JUC并发篇(多线程详细版)_第23张图片

6.2.2 悲观锁与乐观锁代码实现共享变量线程安全

悲观锁展示:
Java---JUC并发篇(多线程详细版)_第24张图片
乐观锁展示:
Java---JUC并发篇(多线程详细版)_第25张图片

7. Hashtable 与 ConcurrentHashMap

7.1 Hashtable 与 ConcurrentHashMap概念区别

1 ConcurrentHashMap与HashMap结构很类似,在每个头结点加了一把锁。
Java---JUC并发篇(多线程详细版)_第26张图片

7.2 ConcurrentHashMap原理细节

  1. 如何put一个元素到HashMap中,根据key计算二次hash值,移位再按位与。(移位再按位与目的:并发度为16时,高4位为索引值)。
  2. 理解ConcuurentHashMap中的capacity 和 factor 与HashMap中的有所区别。
    capacity表示要存放的元素的个数,factor只有第一次初始化时用上,以后还是按0.75扩容。
  3. 扩容细节:一个个的迁移Java---JUC并发篇(多线程详细版)_第27张图片4. 查询:forwardingNode 标志已经迁移过,get操作时去新的map上获取,并不会阻塞。迁移链表过程中下面2个1 不能是同一个对象。
    Java---JUC并发篇(多线程详细版)_第28张图片
  4. put 分三种情况
    0-9 正常put
    10 号正在迁移,头节点锁被占用,被阻塞
    11-15 forwardingNode

8. ThreadLocal

8.1 谈一谈对ThreadLocal的理解

Java---JUC并发篇(多线程详细版)_第29张图片

适用场景:连接数据库获取Connection对象时。
多个线程调用工具类时间格式化会报错,没有考虑线程的安全问题,这个时候threadlocal出现了
链接: 讲解ThreadLocal参考视频.
Java---JUC并发篇(多线程详细版)_第30张图片

用TreadLocal修饰—时间格式化SimpleDateFormat
把这个操作放在threadlocal中,解决线程的安全问题。

8.2 线程间隔离 与 线程内共享

Java---JUC并发篇(多线程详细版)_第31张图片
Java---JUC并发篇(多线程详细版)_第32张图片
ThreadLocalMap解决资源的线程间隔离,ThreadLocal解决线性冲突的方法为:开放寻址放。

你可能感兴趣的:(Java并发编程,Java面经,多线程)