2013-06-04 22 views
5

我正在研究图(节点和顶点)分区算法。多线程写入相同的布尔值

我使用多个线程来尝试和识别图中的某些区域。

一旦节点已被识别为区域的一部分,我将节点对象的boolean marked设置为true。

多个线程可以尝试同时标记同一个节点。

目前我使用同步来确保没有什么不好的事情发生。

但是因为我从来没有在所有线程完成处理后读取已标记的值。我可以摆脱同步代码吗?换句话说,在并发写入布尔变量时,什么都可能出错?

+0

被标记曾经设置为false便宜当它被设置为真? – berry120

+0

nope。只是设置为true –

回答

3

当并发写入布尔变量时,什么都可能出错?

是和否。当然,结果值不会以某种方式被破坏,但是对于哪些更新被设置在字段上以及何时这些更新被其他线程看到 - 如果有的话,它将是非确定性的。

如果您有多个线程正在使用此布尔值的值进行决策,则必须在某个时间点提供内存同步。使字段volatile的成本非常低,除非您有证据表明这是一个性能问题,否则没有该字段为volatile是最可能过早的优化。如果您正在比较并设置,那么推荐使用AtomicBoolean,它包含volatile boolean并提供更高级别的方法,如compareAndSet(...)

0

否。如果写入该变量的顺序无关紧要。

+1

问题是,读者线程可能永远无法观察写入。 – assylias

+0

@assylias即使“在所有线程完成处理之后,我从未读过标记的值”?你可以解释吗? –

+0

编写线程已完成其作业的事实并不意味着所做的更改已正确发布,并且可以从另一个线程读取。 – assylias

2

理论上,不,但我不介意声明变量volatile。易失性关键字确保原子访问。

(前提是写的顺序并不重要,所有读所有的写操作之后发生。)

+2

这不是关于原子访问总是发生在'boolean'上,除非你正在执行一个测试并设置'volatile'不能解救你的操作。这与操作顺序和内存可见性有关。 – Gray

+0

除非有适当的同步,否则虽然编写器线程将布尔值设置为“true”,但读取器线程可能会读取“false”。 *在OP描述中存在*可见性问题。 – assylias

2

没有,没有什么可以去错了,当多个线程写入同一个布尔值,但也有可能是一个问题稍后在另一个线程中读取值(甚至很长时间)。您至少应该将变量标记为volatile以防止出现问题。

1

正如其他人所说,如果您只是试图将它设置为来自多个线程的相同值,那么不存在布尔错误或值不正确的风险。

然而,你可能甚至不需要说

我从来没有看过的标记,直到毕竟线程完成处理的值。

你显然需要某种屏障与工作线程(如Thread.join()CountdownLatch或您的原始大谈特谈)协调线程同步,几乎所有的已经提供的之前发生关系,即会使所有标记对协调器线程可见。

有了这样的同步的单点也恰好是比读了大量挥发物(我不认为这是不成熟的优化,只需eliding挥发性物质的需要)

+0

谢谢..这是有道理的。 (我正在使用thread.join())以及使用易变的布尔值。我将使用布尔值代替易变的布尔值 –

相关问题