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