我正在学习编写线程安全的程序,以及如何评估不是线程安全的代码。
如果一个类在被多个线程执行时能够正确运行,那么它就被认为是线程安全的。
我的Counter.java不是线程安全的,但是对于所有3个线程,输出都是从0到9按预期打印的。
有谁能解释一下原因吗?线程安全是如何工作的呢?
public class Counter {
private int count = 0;
public void increment() {
count++;
}
public void decrement() {
count--;
}
public void print() {
System.out.println(count);
}
}
public class CountThread extends Thread {
private Counter counter = new Counter();
public CountThread(String name) {
super(name);
}
public void run() {
for (int i=0; i<10; i++) {
System.out.print("Thread " + getName() + " ");
counter.print();
counter.increment();
}
}
}
public class CounterMain {
public static void main(String[] args) {
CountThread threadOne = new CountThread("1");
CountThread threadTwo = new CountThread("2");
CountThread threadThree = new CountThread("3");
threadOne.start();
threadTwo.start();
threadThree.start();
}
}发布于 2013-04-06 22:36:03
您的代码在您的特定测试中运行良好。这并不意味着它总是工作得很好。尝试更多的迭代次数,您可能会开始看到异常。
您的测试有点像您测试一座桥可以支持20辆卡车,只需一辆汽车就可以在桥上行驶。它没有展示任何东西。使用测试来证明这段代码是线程安全的几乎是不可能的。只有仔细阅读和理解所有潜在的问题才能保证这一点。一个非线程安全的程序可能会在几年内工作得很好,然后突然出现错误。
为了使您的计数器安全,请使用AtomicInteger。
编辑:
此外,正如@SpringRush所指出的,您不会在线程之间共享单个计数器。每个线程都有自己的计数器。所以你的代码实际上是线程安全的,但是我不认为它做了你想要做的事情。
发布于 2013-04-06 22:34:35
您的Counter不是通过这3个线程共享的,而是每个线程都有一个唯一的Counter
发布于 2013-04-06 22:37:27
所以这实际上是线程安全的。对于每个CountThread,都有一个计数器。要使其不是线程安全的,请将计数器变量更改为:
private static Counter counter = new Counter(); 那么它就不是线程安全的,因为不同的线程可能会同时修改计数器状态。
https://stackoverflow.com/questions/15852123
复制相似问题