diff --git a/blogs/Java/并发/Java 并发编程线程基础.md b/blogs/Java/并发/Java 并发编程线程基础.md index 8025f92..20a30bd 100644 --- a/blogs/Java/并发/Java 并发编程线程基础.md +++ b/blogs/Java/并发/Java 并发编程线程基础.md @@ -10,6 +10,7 @@ Java 并发编程线程基础 4. 让线程睡眠的 sleep 方法 5. 让出 CPU 执行权的 yield 方法 6. 线程中断 +7. 线程死锁 #### 线程的创建与运行 @@ -102,3 +103,55 @@ yield 方法一般用在自旋中。 #### 线程中断 +Java 中的线程中断是一种线程间的协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是被中断的线程根据中断状态自行处理。 + +##### void interrupt() + +中断线程。例如,当线程 A 运行时,线程 B 可以调用线程 A 的 interrupt() 方法设置线程 A 的中断标志为 true 并立即返回。设置标志仅仅是设置标志,线程 A 实际并没有被中断,它会继续往下执行。如果线程 A 因为调用了 wait 系列函数、join 方法或者 sleep 方法而被阻塞挂起,这时候若线程 B 调用线程 A 的 interrupt() 方法,线程 A 会在调用这些方法的地方抛出 InterruptedException 异常而返回。 + +##### boolean isInterrupted() + +检测当前线程是否被中断,如果是返回 true,否则返回 false。 + +```java +public boolean isInterrupted() { + // 传递 false,不清楚标志位 + return isInterrupted(false); +} +``` + +##### Thread.interrupted() + +检测当前线程是否中断,如果是返回 true,否则返回 false。与 isInterrupted 方法不同的是,该方法如果发现当前线程被中断,则会清楚标志位,并且该方法是 static 方法,Thread 类可以直接调用。 + +```java +public static boolean interrupted() { + // 传递 true,清除标志位 + return currentThread().isInterrupted(true); +} +``` + +#### 线程死锁 + +死锁是指两个或多个以上的线程在执行过程中,因争夺资源而造成的相互等待的线程,再无外力的情况下,这些线程会一直相互等待而无法继续运行下去。 + +死锁的产生必须具备以下四个条件: + +* 互斥条件 + + 指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。 + +* 请求并持有条件 + + 指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已经被其他线程占有,所以当前线程会被阻塞,但阻塞的同时并不会释放自己已经获得的资源。 + +* 不可剥夺条件 + + 指线程获取的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完后主动释放该资源。 + +* 环路等待条件 + + 指在发生死锁时,必然存在一个线程-资源的环形链。 + +那么如何避免死锁呢? +