同步语句的NullPointerException
我尝试在下面的代码中同步一个对象:
public void myMethod() { synchronized (globalObj) { //Do something here } }
代码在一个线程中执行。 问题是,另一个线程可能将’globalObj’设置为null。 然后,当’globalObj’被其他线程设置为null时,’synchronized(globalObj)’将抛出NullPointerxception。
什么是在对象上同步的最佳实践,因此不会抛出NullPointerException?
谢谢。
您不应该在可能更改的引用上进行同步。 如果允许另一个线程替换globalObj
,这意味着您可以保持对旧的globalObj
的锁定,而另一个线程在完全不同的线程上工作 – 锁定对您没有任何帮助。
你应该做的是为此目的有一个单独的Object
:
static final Object lockObj = new Object(); public void myMethod() { synchronized (lockObj) { // do something with globalObj here } }
由于lockObj
永远不会改变,所以你总是会使用相同的锁 – 没问题。
您无法在null
引用上进行同步。 最佳实践是在final
对象上进行同步(以确保它永远不为null
),或者(更好地)在java.util.concurrent
包中使用更高级别的并发抽象。
确保在不能为null的对象上进行同步…
为什么globalObj
设置为null? 这应该是什么样的并发语义? 这是偶然的吗?
如果锁定的必要性有时消失(虽然看起来很奇怪),你可以添加一个空检查(当然,你需要同步其他东西以避免首先检查null的竞争条件,然后将其设置为之后立即为null)。
请更详细地描述您的场景。
创建一个私有对象类成员,该成员没有任何公共setter并锁定该成员。
- AsyncTaskLoader,用于处理方向更改的http请求,使用generics,inheritance
- 如何将Mongo DB与Android应用程序连接起来
- 如何在Android中使用JNI获取设备ID?
- java.lang.ClassCastException
- 我应该使用View Holder图案作为我的适配器吗?
- 哈希码编号是否代表内存地址?
- android.content.res.Resources $ NotFoundException:资源ID#0x7f040019
- 没有deleteKey命令从BKS文件丢失密钥
- 如何在App Engine项目中禁用SystemServiceServlet配置?