CodeQL 文档

字段自旋

ID: java/spin-on-field
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - efficiency
   - correctness
   - concurrency
Query suites:
   - java-security-and-quality.qls

单击以查看 CodeQL 仓库中的查询

在空循环语句的条件中反复读取非易失性字段可能会导致无限循环,因为编译器优化可能会将此字段访问移出循环。

示例

在以下示例中,方法 spin 在循环中反复测试字段 done。该方法重复 while 循环,直到字段 done 的值由另一个线程设置。但是,编译器可以优化代码,如第二个代码片段所示,因为字段 done 没有标记为 volatile,并且循环体中没有可以更改 done 值的语句。优化后的 spin 版本将永远循环,即使另一个线程将 done 设置为 true 也是如此。

class Spin {
    public boolean done = false;

    public void spin() {
        while(!done){
        }
    }
}

class Spin { // optimized
    public boolean done = false;

    public void spin() {
        boolean cond = done;
        while(!cond){
        }
    }
}

建议

确保对该字段的访问已正确同步。或者,避免在字段上自旋,而是使用 waitnotifyAll 方法或 java.util.concurrent 库在线程之间进行通信。

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私