线程死锁相关知识点
文章目录
- 一、线程死锁的核心特性
- 二、死锁的典型诱因:同步嵌套
- 三、死锁产生的关键锁特性:不可抢占
- 四、锁的本质与互斥性
一、线程死锁的核心特性
- 不抛掷异常:线程死锁是指两个或多个线程相互等待对方持有的资源。是一种程序运行时的状态异常,而非代码语法或逻辑错误,因此Java等编程语言中,死锁不会主动抛出异常。死锁发生时,相关线程会进入无限期阻塞状态,程序可能表现为卡顿、无响应,但不会有明确的错误提示,需要通过日志分析、线程dump等方式排查。
二、死锁的典型诱因:同步嵌套
- synchronized同步中嵌套同步:这是死锁最常见的场景之一。当线程A持有锁1,同时尝试获取锁2;而线程B持有锁2,同时尝试获取锁1时,就会因互相等待对方释放锁而陷入死锁。
- 示例:
// 线程A的操作 synchronized(lock1) {// 持有lock1后,尝试获取lock2synchronized(lock2) {// 执行操作} }// 线程B的操作 synchronized(lock2) {// 持有lock2后,尝试获取lock1synchronized(lock1) {// 执行操作} }
- 示例:
三、死锁产生的关键锁特性:不可抢占
- 不可抢占锁的定义:指线程获取的锁只能由自身主动释放(如执行完
synchronized
代码块、调用wait()
方法等),其他线程无法强制抢占或剥夺该锁。 - 与死锁的关联:正因为锁不可抢占,当两个线程分别持有对方需要的锁时, neither can force the other to release the lock,只能无限期等待,从而形成死锁。
四、锁的本质与互斥性
- 锁的本质:是控制线程互斥访问共享资源的权限标识。一个锁在同一时刻只能被一个线程持有,其他线程若想获取该锁,必须等待持有线程释放。
- 为什么不会出现两个线程同时占有同一锁:
锁的设计基于互斥原则,其内部通过状态标记(如是否被持有)和等待队列实现。当线程尝试获取锁时,若锁未被持有,则当前线程标记为持有者;若已被持有,则当前线程进入等待队列,直到锁被释放后重新竞争。因此,同一锁不可能被两个线程同时占有,这是保证线程安全的基础。