证明这个类是线程安全的?

时间:2016-11-12 02:23:14

标签: java multithreading

我必须证明(使用代码)一个类(在.jar文件中)不是线程安全的。

我理解问题是什么,我只是不确定如何处理这个问题的编码部分。

2 个答案:

答案 0 :(得分:4)

证明该类不是线程安全的证据可能只是一些代码,它证明了它可以使类以非线程安全的方式运行。 (存在的证明。)

例如,这可能是一个包含两个线程的程序:

  • 一个线程将计数器设置为N并休眠。
  • 第二个线程将计数器递减N次
  • 第一个线程唤醒并测试计数器是否耗尽。

重复几次(百,千,百万)次

如果存在线程安全问题,那么depleted测试可能会给出错误答案。

但是请注意,像这样的线程安全问题的黑盒测试有点受欢迎:

  • 测试的实际行为可能会因硬件平台等而异。

  • 如果将测试中的代码视为黑盒子,您无法确定可能具有哪些线程安全问题,或者如何(确切地)触发它们

  • 在设计这样的测试时,很容易做一些事情来进行某种偶然的同步......这可以防止线程安全问题出现。

您无法清楚地展示线程安全问题并不意味着它们不存在。您无法通过测试来证明代码是线程安全的。

最后,API设计显然不是可重入的。由于方法是static,因此只有一个计数器 1 ,它一次只能用于一件事。但是,这不是线程安全问题。我会将 2 称为API设计/可用性问题,而不是线程安全问题。

1 - ......除非实施真的很奇怪;例如是使用线程本地状态。但是,这应该在API规范中记录。

2 - 如果设置考试问题的人并没有真正达到接受的并发术语的速度,他们就可能不同意我的意见。

答案 1 :(得分:0)

由于 Stephen C 已经给出了全面的答案,我想为他的提案和你提供的方法提供一个Java示例:

public class Tester {

    private static int value;

    public static void main(String[] args) {

        Runnable decrementRunnable = new Runnable() {
            @Override
            public void run() {

                while (!depleted()) {
                    decrement();
                }

            }
        };

        set(10);

        Thread decrementThread = new Thread(decrementRunnable);
        decrementThread.start();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (depleted()) {
            System.out.println("Not thread-safe.");
        }

    }

    private static void set(int i) {
        value = i;
    }

    private static boolean depleted() {
        return value <= 0;
    }

    private static void decrement() {
        value--;
    }

}