GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • 卡码笔记-最强八股文
  • 计算机基础
  • Python
  • C++
  • Java
  • Go
  • ChatGPT充值
  • Claude充值
  • 国内使用Claude
  • 中转站推荐
  • 🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经

This view

  • Original page
  • New address

GeezerVison is showing notes.kamacoder.com — 线程安全|高频面试题|Java高频面试题|synchronized、Lock、CAS、原子类

# 线程安全

# 简要回答

实现Java线程安全,需要控制多个线程对共享资源的并发访问,避免出现数据不一致,竞态条件等问题

可以分为三种方式:

  • 阻塞同步(使用锁实现)
  • 非阻塞同步(基于CAS操作)
  • 无同步方案(避免共享资源)

# 详细回答

  1. 阻塞同步:通过“加锁-释放锁”控制线程对资源的访问,未获取锁的线程会阻塞等待。
  • synchronized关键字(隐式锁)
    • 通过JVM隐式管理锁,对对象或者类加锁,确保同一时间只有一个线程执行同步代码。
//同步方法
public synchronized void setA(){
  // 执行代码逻辑
}

//同步代码块
public void setB(){
  synchronized (this){
  // 执行代码逻辑
  }
}
1
2
3
4
5
6
7
8
9
10
11
  • JUC显式锁(Lock接口)
    • 通过ReentrantLock手动加锁和释放锁,能够支持更复杂的同步场景,比如公平锁、超时释放、中断。
    • 通过读写锁,允许多个读取者同时访问共享资源,但只允许一个写入者。
  1. 非阻塞同步
  • 原子类(CAS操作):通过循环重试保证变量的更新。
  • 版本号机制:乐观锁,通过版本号来判断数据是否被修改,仅在提交时校验。
  • 优缺点:
    • 避免线程阻塞,唤醒线程开销以及用户态内核态切换带来的性能问题。
    • 过度自旋会浪费CPU资源。
    • 仅能操作单个共享资源,对于组合类型还是需要加锁处理,或者重新组合为一个共享资源。
    • ABA问题
  1. 无同步方案:让共享资源尽可能的在同一个线程中执行。
  • 线程本地存储:为线程创建独立的资源副本,无需同步
  • 创建不可变对象

# 使用场景

实现方式 适用场景
阻塞方式 共享资源操作复杂、资源竞争不激烈、需要严格保证资源独占性场景
非阻塞操作 高频/简单操作、重试成本低、不允许线程阻塞场景
无同步方案 数据仅线程私有、数据不可修改、业务逻辑不依赖状态

# 知识图解

  1. ABA问题示意图 image

  2. 读写锁使用示意图 image

# 知识扩展

  1. 扩展:
  • ABA问题:
    • 在CAS更新的过程中,读取到的值是A,准备赋值时是A,但是其实是因为A的值先变成B又被改成了A。
    • ABA漏洞在大部分场景下不会影响最终结果,可以通过Java中的AtomicStampedReference来解决问题,该类会加入预期标志和更新后标志两个字段,更新时不光检查值,还要检查当前标志是否等于预期标志,相等则更新。
  1. 面试官可能追问:
  • Q1:原子类的底层原理是什么?
    • 底层是CAS指令+volatile+自旋重试的组合。CAS保证操作的原子性,volatile保证变量的可见性,自旋重试解决并发冲突。
  • Q2:线程安全体现在哪些方面?
    • 原子性:提供互斥访问,同一时刻只有一个线程对数据进行操作。
    • 可见性:线程对主存修改可以及时被其他线程看到。
    • 有序性:线程中的指令执行有序。可以使用happens-before原则实现。

← 线程start和run的区别? synchronized和lock、reentrantlock的区别是什么? →

评论

验证登录状态...

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.