使用潜在危险函数¶
ID: java/potentially-dangerous-function
Kind: problem
Security severity: 10.0
Severity: warning
Precision: medium
Tags:
- reliability
- security
- external/cwe/cwe-676
Query suites:
- java-security-extended.qls
- java-security-and-quality.qls
此规则查找对危险使用的函数的调用。目前,它检查对 Thread.stop
的调用。
使用 Thread.stop
停止线程会导致它收到一个 ThreadDeath
异常。该异常向上传播堆栈,释放线程持有的所有监视器。在某些情况下,相关代码将通过捕获 ThreadDeath
异常并进行清理来保护,但由于异常可能从非常多的位置抛出,因此无法捕获所有这些情况。因此,调用 Thread.stop
可能会导致数据损坏。
建议¶
最佳解决方案通常是为可能需要提前中断的线程提供替代的通信机制。例如,Oracle 提供了以下使用 volatile 变量来通信工作线程是否应该退出的示例
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
也可以使用 Thread.interrupt
,并在发生时捕获和处理 InterruptedException
。但是,可能难以在可能发生 InterruptedException
的所有地方处理它;例如,上面的示例代码只是丢弃了异常,而不是实际退出线程。
另一种策略是使用消息传递,例如通过 BlockingQueue
。除了通过这种消息队列传递工作线程的常规工作之外,还可以通过向队列发送特定类型的消息来要求工作线程退出。
参考资料¶
SEI CERT Oracle Java 编码标准:THI05-J. 不要使用 Thread.stop() 来终止线程.
Java API 规范:Java 线程原语弃用.
Java API 规范:Thread.interrupt,BlockingQueue.
常见弱点枚举:CWE-676.