Java线程管理与并发编程:方法与策略
发布时间: 2025-08-17 02:17:21 阅读量: 1 订阅数: 3 

### Java 线程管理与并发编程:方法与策略
在 Java 编程中,线程管理和并发编程是至关重要的部分。本文将深入探讨线程的取消、资源控制、多阶段取消以及守护方法等方面的知识。
#### 1. 线程取消与资源控制
在 Java 中,线程的取消操作需要谨慎处理。`Thread.stop` 方法虽然可以尝试终止线程,但它并不比 `Thread.interrupt` 更能保证线程的终止,而且更加危险。因为任何执行中的方法都可以捕获并忽略 `Thread.stop` 抛出的 `ThreadDeath` 异常。
当涉及到加载和执行外部代码的系统设计时,取消操作可能会面临挑战。外部代码可能会忽略所有中断,甚至捕获并丢弃 `ThreadDeath` 异常,使得 `Thread.interrupt` 和 `Thread.stop` 无效。为了控制这种情况,可以采取以下措施:
- **资源拒绝**:创建并使用 `SecurityManager` 及其相关类,当线程运行时间过长时,拒绝所有已检查的资源请求。这种资源拒绝方式结合资源撤销策略,可以防止外部代码与其他需要继续运行的线程争夺资源,最终可能导致线程因异常而失败。
- **降低优先级**:调用 `setPriority(Thread.MIN_PRIORITY)` 方法,将线程的优先级设置为最低,以减少对 CPU 资源的竞争。同时,可以使用 `SecurityManager` 防止线程重新提高优先级。
#### 2. 多阶段取消
有时候,普通代码也需要以更极端的方式取消。为了应对这种情况,可以设置一个通用的多阶段取消机制,该机制首先尝试以最小干扰的方式取消任务,如果任务未能及时终止,则采用更具破坏性的技术。
以下是一个多阶段取消的示例代码:
```java
class Terminator {
// Try to kill; return true if known to be dead
static boolean terminate(Thread t, long maxWaitToDie) {
if (!t.isAlive()) return true; // already dead
// phase 1 -- graceful cancellation
t.interrupt();
try { t.join(maxWaitToDie); }
catch(InterruptedException e){} // ignore
if (!t.isAlive()) return true; // success
// phase 2 -- trap all security checks
theSecurityMgr.denyAllChecksFor(t); // a made-up method
try { t.join(maxWaitToDie); }
catch(InterruptedException ex) {}
if (!t.isAlive()) return true;
// phase 3 -- minimize damage
t.setPriority(Thread.MIN_PRIORITY);
return false;
}
}
```
在这个示例中,`terminate` 方法本身会忽略中断,这反映了一旦开始取消尝试就必须继续的策略选择。由于不同 JVM 实现中 `Thread.isAlive` 方法的行为可能存在差异,该方法可能会在被终止线程的所有痕迹消失之前返回 `true`。
#### 3. 守护方法
保守的检查 - 行动方法在不能确保操作成功时会拒绝执行操作,这通常通过首先检查前置条件来实现。根据前置条件失败时的策略决策,守护方法主要有以下三种类型:
| 类型 | 描述 | 示例 |
| ---- | ---- | ---- |
| 拒绝(Balking) | 当前置条件失败时抛出异常,异常表示拒绝而非失败。在某些情况下,拒绝方法也可以不抛出异常。 | `Thread.start` 方法在线程已经启动时会抛出 `IllegalThreadStateException`;`ParticleApplet.stop` 方法在小程序未运行时会忽略停止尝试。 |
| 守护挂起(Guarded Suspension) | 暂停当前方法调用(及其关联的线程),直到前置条件变为真。 | |
| 超时(Time - outs) | 介于拒绝和挂起之间的情况,为等待前置条件变为真设置一个上限时间。 | |
没有一种策略在所有情况下都是最佳的,通常可以创建多个方法来支持多种策略,让客户端进行选择。
#### 4. 守护挂起
守护挂起和超时在顺序程序中没有类似的概念,但在并发软件中起着核心作用。在深入探讨实现细节之前,先考虑一个简单的 `BoundedCounter` 示例:
```java
interface BoundedCounter {
static final long MIN = 0; // minimum allowed value
static final long MAX = 10; // maximum allowed value
long count(); // INV: MIN <= count() <= MAX
// INIT: count() == MIN
void inc(); // only allowed when count() < MAX
void dec(); // only allowed when count() > MIN
}
```
这个示例表示 `BoundedCounter` 的实现必须将计数保持在 `MIN` 和 `MAX` 之间。
##### 4.1 守护条件
守护方法可以看作是同步方法的可定制扩展,提供了更广泛的排他性形式。普通同步方法的“守护条件”是对象处于就绪执行状态,即不参与任何活动。而守护方法通过添加基于状态的条件(如 `count() < MAX`)进一步划分就绪状态,这些条件是操作继续执行的逻辑必要条件。
守护条件也可以被视为特殊形式的条件语句。在顺序程序中,`if` 语句可以在方法入口检查条件,但如果条件为假,等待其变为真没有意义,因为没有其他并发活动可以改变条件。而在并发程序中,异步状态变化随时可能发生。
0
0
相关推荐








