Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/java/concurrent/java-concurrent-questions-01.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ new 一个 `Thread`,线程进入了新建状态。调用 `start()`方法,会

先从总体上来说:

- **从计算机底层来说:** 线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
- **从计算机底层来说:** 线程可以比作是轻量级的进程,是程序执行的最小单位线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
- **从当代互联网发展趋势来说:** 现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。

再深入到计算机底层来探讨:
Expand Down Expand Up @@ -265,7 +265,7 @@ Java 使用的线程调度是抢占式的。也就是说,JVM 本身不负责

## ⭐️死锁

### 什么是线程死锁?
### 什么是线程死锁

线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

Expand Down Expand Up @@ -323,14 +323,14 @@ Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1
```

线程 A 通过 `synchronized (resource1)` 获得 `resource1` 的监视器锁,然后通过`Thread.sleep(1000);`让线程 A 休眠 1s 为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。
线程 A 通过 `synchronized (resource1)` 获得 `resource1` 的监视器锁,然后通过 `Thread.sleep(1000);` 让线程 A 休眠 1s为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。

上面的例子符合产生死锁的四个必要条件:

1. 互斥条件:该资源任意一个时刻只由一个线程占用。
2. 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
3. 不剥夺条件:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
4. 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
1. **互斥条件**:该资源任意一个时刻只由一个线程占用。
2. **请求与保持条件**:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
3. **不剥夺条件**:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
4. **循环等待条件**:若干线程之间形成一种头尾相接的循环等待资源关系。

### 如何检测死锁?

Expand Down