这是一个简单的非线程安全的Counter类,我想让线程安全。
public class Counter{
private static int val = 0;
public Counter() {
}
public static void set(int newVal) {
val = newVal;
}
public static void decrement() {
int tmp = val;
try {
Thread.sleep(100L);
} catch (Exception var2) {
;
}
--tmp;
val = tmp;
}
public static boolean depleted() {
return val == 0;
}
}
我知道synchronised
方式,并已在下面实施:
public static synchronised void decrement() {
val--
}
现在我试图弄清楚任何其他简单的方法来使类线程安全吗?
特别是我正在查看java库java.util.concurrent
和atomic data structures
。我将如何实施这些?即使是对它们的解释,也像伪代码一样,将不胜感激。
谢谢
编辑:为什么选票?我想学习:(
答案 0 :(得分:0)
简单的方法是:
Counter
synchronized
。Counter
类成为AtomicInteger
实例的包装器。AtomicInteger
。值得注意的是,这是个坏主意:
try {
Thread.sleep(100L);
} catch (Exception var2) {
;
}
正确实施的计数器不应随意延迟通话。它不属于"规范" (即预期行为)柜台。
如果sleep(100L)
调用的目的是(以某种方式)帮助您证明您的计数器代码是线程安全的,那么它就赢了:
通过运行代码并查看代码是什么来证明代码是线程安全的 这种方法只会给你无效的证明"以及对你的代码正在做什么的错误认识。
由于Thread.sleep(...)
调用的某些未指定的同步效果,它实际上可能导致偶然的同步。添加sleep
(或打印或日志语句)可能会更改行为多线程代码。 (就像使用调试器运行它一样。)
另外,抓住Exception
是坏主意。捕获您期望的特定异常。捕捉"一切"可以使您捕获实际上代码中的错误证据。 (一般情况下,如果不在这里。)这样做是一个糟糕的编码习惯,很可能会在将来的某个时候伤害你。
答案 1 :(得分:0)
使用AtomicInteger
代替整数来跟踪coints。
它提供了诸如decrementAndGet
和getAndSet(int newValue)
等原子方法。