假设我有一个
private static Object lock = new Object();
和同一类
中的某个位置public void run() {
synchronized(lock) {
//only 1 thread here, all others wait
}
}
我总是读到锁对象应该是final,但不清楚为什么。假设我100%知道我的代码不会触及任何地方的锁对象,如果省略最后一个关键字,这是否意味着同步是不是100%防弹的
?在这种情况下使用final
是一种良好的实践。
您可以使用任何对象同步,final
或非final,static
或非static。
同时使用final
和static
将为您提供安全性,没有人会在不同的锁上同步相同的代码。不使用final
,你不能确定在代码的某个地方变量没有被重新分配。
一般来说,对一个变量使用final
是一个很好的编程实践,它在初始化后永远不会被重新赋值。它提高了可读性,因为读你代码的人知道,如果不读完整的代码,这个变量也不会被重新赋值。
如果没有最后的修饰符,您将依赖于对象初始化以使其正确可见,并假设没有改变其值。由于它是静态的,因此在装入类时进行初始化,并且有可见性保证,因此从技术上讲,您可以将其保留为非final。(虽然代码使用了一个同步块,但是在进入块之前必须先计算正在使用的锁)
如果锁对象在使用过程中被更改为另一个锁对象,那么两个线程可能处于受保护代码的同一段中,并且整个锁定方案受到损害。在这里添加final关键字意味着编译器正在帮助您确保此锁不会更改,并且如果稍后有人试图更改它将导致编译错误。
从编译器那里得到尽可能多的帮助通常是一件好事,编译器会告诉你字段是否被更改了,所以这样做的风险很低,可以确保不会发生大问题。