java 同步语句上的 NullPointerException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6433493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NullPointerException on synchronized statement
提问by Kai
I tried to synchronize on an object in my code below:
我尝试在下面的代码中同步一个对象:
public void myMethod() {
synchronized (globalObj) {
//Do something here
}
}
The code is executed in one thread. The issue is that, another thread may set 'globalObj' to null. Then, 'synchronized (globalObj)' will throw NullPointerxception when 'globalObj' has been set to null by other threads.
代码在一个线程中执行。问题是,另一个线程可能将“globalObj”设置为 null。然后,当 'globalObj' 已被其他线程设置为 null 时,'synchronized (globalObj)' 将抛出 NullPointerxception。
What's the best practice to synchronize on an object so NullPointerException will not be thrown?
在对象上同步以便不会抛出 NullPointerException 的最佳实践是什么?
Thanks.
谢谢。
回答by bdonlan
You should not be synchronizing on a reference that itself may be changed. If another thread is allowed to replace globalObj
, that means you might hold a lock to the old globalObj
while another thread works on an entirely different one - the lock doesn't help you at all.
您不应该对本身可能会更改的引用进行同步。如果允许另一个线程替换globalObj
,这意味着您可能持有旧globalObj
线程的锁,而另一个线程在一个完全不同的线程上工作 - 锁根本没有帮助您。
What you should do instead is have a separate Object
for this purpose:
你应该做的是Object
为此目的有一个单独的:
static final Object lockObj = new Object();
public void myMethod() {
synchronized (lockObj) {
// do something with globalObj here
}
}
Since lockObj
never changes, you'll always use the same lock - no problems.
由于lockObj
永远不会改变,您将始终使用相同的锁 - 没问题。
回答by Daniel
You can't synchronize on a null
reference. The best practice is to synchronize on a final
object (to ensure that it's never null
), or (better still) use the higher level concurrency abstractions in the java.util.concurrent
packages.
您无法在null
参考上同步。最佳实践是在final
对象上进行同步(以确保它永远不会null
),或者(更好)在java.util.concurrent
包中使用更高级别的并发抽象。
回答by Thilo
Make sure you synchronize on an object that cannot be null...
确保在不能为空的对象上进行同步...
Why are you setting the globalObj
to null? What should be the concurrency semantics for this? Is it by accident?
为什么要设置globalObj
为空?这应该是什么并发语义?是偶然吗?
If the necessity to lock goes away sometimes (seems weird, though), you can add a null check (of course, you would need to synchronize on something else to avoid a race condition of first checking for null, and then having it set to null immediately afterwards).
如果锁定的必要性有时消失(虽然看起来很奇怪),您可以添加一个空检查(当然,您需要同步其他内容以避免首先检查空值,然后将其设置为之后立即为空)。
Please describe your scenario in more detail.
请更详细地描述您的场景。
回答by Marcus Leon
Create a private object class member which does not have any public setters and lock on that.
创建一个没有任何公共 setter 的私有对象类成员并锁定它。