这似乎是一个非常愚蠢的问题。 考虑一下:
我有一个带有getter和setter的简单Boolean对象。现在,很多线程都经常调用这两种方法。
[UPDATE]: 我已经知道Atomic布尔了。我已经有了很多不同的解决方案,但我是专门为上述2个问题寻找答案和答案的理由。
答案 0 :(得分:10)
答案 1 :(得分:3)
是。但是,如果它是仅从一个线程编写的标志,并且您希望确保所有线程的可见性,那么便宜的替代方案是使用volatile
。
是 - 即使对象的内部表示(即boolean
包装器中的实际Boolean
标志)是64位,因此可能在并发情况下“分裂” ,布尔值只能有两个值中的一个,对吧?所以普通的赋值(get 或集)是原子的,但是如果你正在做其他事情(比如check-then-act),例如x = !x
,那么除非同步,否则它当然不是原子的。
答案 2 :(得分:3)
volatile
或synchronized
来实现之前发生的边缘。这两种技术都会产生同步边缘。因此,在实践中,您可能会使用同步来管理布尔值的状态。更新:让我解释一下前发生边缘的必要性。如果没有先发生边缘,那么一个线程对变量所做的更改就不能保证被其他线程所感知。不仅可以在诸如读取和写入之间的不良时间感知改变。这种变化可能从未被感知。
假设我们有一个布尔变量,我们将其初始化为false。然后我们开始两个线程。第一个线程将变量设置为true并停止。第二个线程不断检查变量,直到它为真,然后停止。无法保证第二个线程会将变量视为真。
答案 3 :(得分:2)
答案 4 :(得分:1)
不,你没有。但是声明变量volatile
,以便这些值反映在访问布尔值的所有线程中。如果您查看AtomicBoolean
的{{1}}方法,它也没有任何同步。
是的,实际上分配是原子的。只是设置值不需要同步。但是,如果你想做类似的事情:
set(..)
然后你需要同步(或if (!bool) {
bool = false;
}
,这比同步更有效)
答案 5 :(得分:1)
http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html 说原始变量的读写是原子的。
因此可以强制执行严格的交替,或者在使用布尔值的关系之后执行(或者在缓存效果的情况下使用volatile布尔值)
答案 6 :(得分:0)
即使它是原子的,仍然存在同步问题,因为您可能会在某个时间检查该值 例如 if(boolVar == true) - >其他线程控制do_something();