像下面的示例代码一样。
我将使用线程池在期间运行TestRunnable的对象。
我应该将变量total声明为volatile吗?
public class TestRunnable implements Runnable {
private int total;
@Override
public void run() {
if (total > 10) {
return;
} else {
total += 1;
System.out.print("Run in times: " + total);
}
}
}
答案 0 :(得分:1)
假设您的变量被声明为
private int total;
(非静态)
它不会在多个线程之间共享(只要您继续为每个提交的线程创建新实例),所以不需要将其声明为volatile。
如果您多次使用同一个实例 - 那么您应该考虑使用 AtomicInteger 而不是常规 int ,因为操作
total+= 1;
或
total++;
不是原子操作,可能会导致多线程环境中出现意外结果。
答案 1 :(得分:0)
即使您要标记字段volatile
,由于if
语句不是原子的,因此没有任何价值。请考虑以下情况:
TestRunnable
' run()
方法。total > 10
的评估结果为false
,因为total
为10。else
分支并尝试增加变量。total
尚未增加。total
,这可能会使其处于不一致状态。请注意,只有在您向池中多次提交相同的实例时才会发生这种情况(至少这是我能想到的唯一情况)。但是,由于您在Runnable
内管理状态 - 这对我来说似乎不对,这可能是您正在做的事情。
正如@DmitriyKotov指出的那样,您应该切换到AtomicInteger
。从Java 8开始,您可以轻松完成:
total.getAndUpdate(currentVal -> currentVal > 10 ? currentVal : currentVal + 1);