Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用findbugs或其他分析工具检测竞争条件_Java_Thread Safety_Findbugs - Fatal编程技术网

Java 使用findbugs或其他分析工具检测竞争条件

Java 使用findbugs或其他分析工具检测竞争条件,java,thread-safety,findbugs,Java,Thread Safety,Findbugs,Below bean不是线程安全的:addIfNotExist方法是不同步的,因此可能由于竞争条件,同一术语被添加了两次。我使用JCIP annotation@ThreadSafe对该类进行了注释,希望FindBugs会发现该实现不是线程安全的,并将其标记为错误,但事实并非如此。是否有任何工具可以在代码库中识别这些类型的错误 方法AddifyNotExist和isExist应该同步以使这个bean线程安全。isExist方法是否也应该同步 package com.test; import ja

Below bean不是线程安全的:addIfNotExist方法是不同步的,因此可能由于竞争条件,同一术语被添加了两次。我使用JCIP annotation@ThreadSafe对该类进行了注释,希望FindBugs会发现该实现不是线程安全的,并将其标记为错误,但事实并非如此。是否有任何工具可以在代码库中识别这些类型的错误

方法AddifyNotExist和isExist应该同步以使这个bean线程安全。isExist方法是否也应该同步

package com.test;

import java.util.ArrayList;

import java.util.Collection;

import net.jcip.annotations.GuardedBy;

import net.jcip.annotations.ThreadSafe;

@ThreadSafe

public class Dictionary {

    @GuardedBy("this")
    public Collection<String> terms = new ArrayList<String>();

    public void addIfNotExist(final String input) {
        if (!this.terms.contains(input)) {
            this.terms.add(input);
        }
    }

    public boolean isExist(final String input){
        return this.terms.contains(input);
    }

    public void remove(final String input){
        this.terms.remove(input);
    }
}
package.com.test;
导入java.util.ArrayList;
导入java.util.Collection;
导入net.jcip.annotations.GuardedBy;
导入net.jcip.annotations.ThreadSafe;
@线程安全
公共类词典{
@担保人(“本”)
public Collection terms=new ArrayList();
public void addIfNotExist(最终字符串输入){
如果(!this.terms.contains(输入)){
此.terms.add(输入);
}
}
公共布尔值isExist(最终字符串输入){
返回此.terms.contains(输入);
}
公共无效删除(最终字符串输入){
此.terms.remove(输入);
}
}
编写具有任意复杂度的安全多线程代码是非常困难的:这种类型的锁定(使用监视器)充满了各种间歇性的竞争条件、死锁和活锁问题,这些问题往往会在推广到生产系统时逃避检测;如果可以,考虑使用,或者代替。

FindBugs(或者任何静态分析工具)在检测非线程安全代码方面只能做到这一点:根据它们的定义,竞争条件是时间敏感的——它们需要多次执行才能实现,因此静态分析在这方面失败,因为它们不运行任何代码,只查找公共代码签名。IMHO检测问题的最佳方法是:

  • 第二双眼睛——与熟悉代码的同事一起进行严格的代码审查——一直在寻找对原始作者来说不明显的bug

  • 持续集成&在各种硬件上执行多线程的彻底自动化测试,并对任何“间歇性”测试失败进行调查

在回答第二个问题时,是的,所有引用
术语的方法都应该受到同步监视器的保护,无论是写操作还是读操作;考虑如果线程A调用<代码>删除(“BOB”)<代码>会发生什么,而线程B正在调用<代码> Is存在(“Bob”)< /代码>当没有同步时,线程A将压缩数组列表,而线程B将试图遍历它。p>
充其量,您将无法确定isExists(“BOB”)
的结果,但完全有可能B会间歇性抛出一个
IndexOutOfBounds
异常,因为数组的大小在遍历过程中可能已经改变(即缩小)


同步,虽然您仍然无法确定调用的顺序(由于调度的不确定性),但至少可以保证对
项的操作是原子的,也就是说,在当前线程运行时,它们不会被其他内容更改。

这是您可以在运行时(在自动单元测试或集成测试期间或您所做的其他操作)使用的内容,以帮助查找线程问题:

比赛内容:
“ConTest技术具有创新性和反直观性。具体而言,ConTest系统且透明地安排程序线程的执行,从而使可能包含竞态条件、死锁和其他间歇性错误(统称为同步问题)的程序场景被迫以高速度出现频率。通过这样做,ConTest大大提高了测试质量并降低了开发成本,因为在测试过程的早期就发现了bug。”

要找到这种不正确同步的代码块,我使用以下算法:

使用仪器记录所有现场修改的螺纹。如果一个字段被多个线程修改而没有同步,那么我发现了一个数据竞争


我在内部实现了这个算法,这是一个在java程序中查找数据竞争的动态工具。

谢谢你的回答——你关于iExists为什么应该同步的推理是有道理的。在哪里可以下载?我发现的只是死链接和空搜索结果。