Java 是否允许在新布尔值上同步(true)

Java 是否允许在新布尔值上同步(true),java,concurrency,synchronized,Java,Concurrency,Synchronized,我很清楚,在Boolean上进行同步不是一个好的做法。 有很多解释为什么它不好,例如: 等等 很明显,这是一种不好的做法: 代码在装箱的基本常量上同步,例如 布尔型 我感兴趣的是,如果我们使用“new”运算符创建最终静态布尔值,会发生什么情况,即类似这样的情况(这是我没有编写的真实代码,但我维护了它,方法名称等发生了更改): 使用它是否“合法”?与我们使用的对象相同,例如: private final Object lock = new Object(); 或 那很好。您的第一个代码段存

我很清楚,在Boolean上进行同步不是一个好的做法。 有很多解释为什么它不好,例如:

等等

很明显,这是一种不好的做法:

代码在装箱的基本常量上同步,例如 布尔型

我感兴趣的是,如果我们使用“new”运算符创建最终静态布尔值,会发生什么情况,即类似这样的情况(这是我没有编写的真实代码,但我维护了它,方法名称等发生了更改):

使用它是否“合法”?与我们使用的对象相同,例如:

private final Object lock = new Object();


那很好。您的第一个代码段存在两个问题,不是因为它是一个
布尔值,而是首先,此行中的对象发生了更改:

 inited = Boolean.TRUE;
因此,可以在旧对象上同步一些线程,在新对象上同步一些线程。这意味着,两个组之间没有同步


其次,
Boolean.TRUE
Boolean.FALSE
是全局对象,如果它们在其他地方以类似的方式使用,这将产生一些难以检测的同步问题(感谢Mark Rotterveel指出)。

这很好。您的第一个代码段存在两个问题,不是因为它是一个
布尔值,而是首先,此行中的对象发生了更改:

 inited = Boolean.TRUE;
因此,可以在旧对象上同步一些线程,在新对象上同步一些线程。这意味着,两个组之间没有同步


其次,
Boolean.TRUE
Boolean.FALSE
是全局对象,如果它们在其他地方以类似的方式使用,这将产生一些难以检测的同步问题(感谢Mark Rotterveel指出)。

您正在对象引用上进行同步。创建
私有最终对象锁=新对象()
的效果与
private final static Boolean lock=new Boolean(true)的效果相同。在这种情况下,您只需要一个唯一的对象

但是您应该小心,因为
newboolean(true)
将创建新的对象引用。如果您尝试使用
Boolean.TRUE
TRUE
它们本质上是内部的,将使用相同的实例,例如:

Boolean bool1 = new Boolean(true);
Boolean bool2 = Boolean.TRUE;
Boolean bool3 = true;

System.out.println(System.identityHashCode(bool1));
System.out.println(System.identityHashCode(bool2));
System.out.println(System.identityHashCode(bool3));
将打印

1433743869
19203296
19203296
因此,在
bool1
上同步将与
bool2
bool3
相互排斥,但2和3将共享独占性


注意
identityHashCode
将为您提供参考哈希代码,告诉您哪些对象是相等的。

您正在对象参考上同步。创建
私有最终对象锁=新对象()
的效果与
private final static Boolean lock=new Boolean(true)的效果相同。在这种情况下,您只需要一个唯一的对象

但是您应该小心,因为
newboolean(true)
将创建新的对象引用。如果您尝试使用
Boolean.TRUE
TRUE
它们本质上是内部的,将使用相同的实例,例如:

Boolean bool1 = new Boolean(true);
Boolean bool2 = Boolean.TRUE;
Boolean bool3 = true;

System.out.println(System.identityHashCode(bool1));
System.out.println(System.identityHashCode(bool2));
System.out.println(System.identityHashCode(bool3));
将打印

1433743869
19203296
19203296
因此,在
bool1
上同步将与
bool2
bool3
相互排斥,但2和3将共享独占性

注意
identityHashCode
将为您提供参考哈希代码,告诉您哪些对象是相等的。

因为
新布尔(…)
为您提供了一个全新的
对象
,使用
新布尔(…)
新对象()
对于您的
来说,实际上
布尔值
有一个与之关联的
true
false
值,而
对象
没有

您可以通过以下代码段检查调用
new Boolean(…)
是否获得新对象:

Boolean bt = Boolean.TRUE;
Boolean bf = Boolean.FALSE;
for (int i = 0 ; i != 20 ; i++) {
    Boolean b = new Boolean(i % 2 == 0);
    System.out.println(b);
    System.out.println("==true : "+(b==bt));
    System.out.println("==false: "+(b==bf));
}
这张照片

true
==true : false
==false: false
false
==true : false
==false: false
true
==true : false
==false: false
false
==true : false
==false: false
...
这意味着您获得的对象与
布尔值.TRUE
布尔值.FALSE
不同

注意:尽管这种做法看起来完全无害,但我认为尝试在
布尔值
整数
、字符串
或任何其他不可变对象上进行同步没有任何意义,因为与在
对象锁定=新对象()上进行同步相比,它没有任何优势,虽然不是那么容易辨认的成语。这反映在代码的可读性上,因为阅读代码的程序员会对您锁定
新布尔(…)
的决定感到困惑,因为
新布尔(…)
为您提供了一个全新的
对象
,使用
新布尔(…)
新对象()
对于您的
来说,实际上
布尔值
有一个与之关联的
true
false
值,而
对象
没有

您可以通过以下代码段检查调用
new Boolean(…)
是否获得新对象:

Boolean bt = Boolean.TRUE;
Boolean bf = Boolean.FALSE;
for (int i = 0 ; i != 20 ; i++) {
    Boolean b = new Boolean(i % 2 == 0);
    System.out.println(b);
    System.out.println("==true : "+(b==bt));
    System.out.println("==false: "+(b==bf));
}
这张照片

true
==true : false
==false: false
false
==true : false
==false: false
true
==true : false
==false: false
false
==true : false
==false: false
...
这意味着您获得的对象与
布尔值.TRUE
布尔值.FALSE
不同

注意:尽管这种做法看起来完全无害,但我认为尝试在
布尔值
整数
、字符串
或任何其他不可变对象上进行同步没有任何意义,因为与在
对象锁定=新对象()上进行同步相比,它没有任何优势,虽然不是那么容易辨认的成语。这反映在代码的可读性上,因为阅读代码的程序员会对您锁定
新布尔值(…)
的决定感到困惑,因为
新布尔值(true)!=新布尔值(true)
,您可以使用这样的锁

但是要小心,因为
Boolean.valueOf(true)=Boolean.valueOf(true