gpt4 book ai didi

java - 为什么在 boolean 值上同步不是一个好习惯?

转载 作者:IT老高 更新时间:2023-10-28 21:02:15 32 4
gpt4 key购买 nike

我的建筑师总是这么说

Never synchronize on Boolean

我无法理解其中的原因,如果有人能举例说明为什么这不是一个好的做法,我将不胜感激。 Reference Sample Code

private Boolean isOn = false;
private String statusMessage = "I'm off";
public void doSomeStuffAndToggleTheThing(){

// Do some stuff
synchronized(isOn){
if(isOn){
isOn = false;
statusMessage = "I'm off";
// Do everything else to turn the thing off
} else {
isOn = true;
statusMessage = "I'm on";
// Do everything else to turn the thing on
}
}
}

最佳答案

I am not able to understand the reason why we should "never synchronize on Boolean"

您应该始终在常量对象实例同步。如果您在您分配的任何对象上同步(即将对象更改为新对象),那么它不是恒定的,不同的线程将在不同的对象上同步 instances。因为它们在不同的对象实例上同步,所以多个线程将同时进入 protected block ,并且会发生竞争条件。这与在 LongInteger 等上同步的答案相同。

// this is not final so it might reference different objects
Boolean isOn = true;
...
synchronized (isOn) {
if (isOn) {
// this changes the synchronized object isOn to another object
// so another thread can then enter the synchronized with this thread
isOn = false;

更糟糕的是,通过自动装箱 (isOn = true) 创建的任何 BooleanBoolean.TRUE (或 .FALSE),它是 所有对象ClassLoader 中的单例。你的锁对象应该是它所使用的类的本地对象,否则你将锁定同一个单例对象,如果其他类犯了同样的错误,其他类可能会锁定它们。

如果您需要锁定一个 boolean 值,正确的模式是定义一个 private final 锁定对象:

private final Object lock = new Object();
...

synchronized (lock) {
...

或者您也应该考虑使用 AtomicBoolean 对象,这意味着您可能根本不需要对其进行 synchronize

private final AtomicBoolean isOn = new AtomicBoolean(false);
...

// if it is set to false then set it to true, no synchronization needed
if (isOn.compareAndSet(false, true)) {
statusMessage = "I'm now on";
} else {
// it was already on
statusMessage = "I'm already on";
}

在您的情况下,因为看起来您需要使用线程打开/关闭它,所以您仍然需要在 lock 对象上 synchronize 并设置 boolean 值并避免测试/设置竞争条件:

synchronized (lock) {
if (isOn) {
isOn = false;
statusMessage = "I'm off";
// Do everything else to turn the thing off
} else {
isOn = true;
statusMessage = "I'm on";
// Do everything else to turn the thing on
}
}

最后,如果您希望 statusMessage 可以从其他线程访问,则应将其标记为 volatile,除非您在也可以。

关于java - 为什么在 boolean 值上同步不是一个好习惯?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10324272/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com