我必须证明(使用代码)一个类(在.jar文件中)不是线程安全的。
我理解问题是什么,我只是不确定如何处理这个问题的编码部分。
答案 0 :(得分:4)
证明该类不是线程安全的证据可能只是一些代码,它证明了它可以使类以非线程安全的方式运行。 (存在的证明。)
例如,这可能是一个包含两个线程的程序:
重复几次(百,千,百万)次
如果存在线程安全问题,那么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--;
}
}