java中的空检查和侦听器



我经常看到这样的代码:

Listener mListener;
public void setListener(Listener listener){
   mListener=listener;
}
public void fooFunction(){
   ...
   ...
   if (mListener!=null){
      mListener.notifyFoo();
   }
}

我的问题是:如果在null检查和notifyFoo()之间,另一个线程调用setListener(null),该怎么办?这可能吗?还是编译器使其成为原子

您可以同步方法

public synchronized void setListener(Listener listener){
   mListener=listener;
}
public synchronized void fooFunction(){
   ...
   ...
   if (mListener!=null){
       mListener.notifyFoo();
   }
}

或者如果你想要更好的锁粒度

private Object monitor = new Object();
public void setListener(Listener listener){
   synchronized (monitor) {
       mListener=listener;
   }
}
public void fooFunction(){
   ...
   ...
   synchronized (monitor) {
        if (mListener!=null){
           mListener.notifyFoo();
       }
   }
}

您可以通过使块同步来避免这种情况

public synchronized void setListener(Listener listener) {
    ....
}
public synchronized void fooFunction() {
    ....
}

默认情况下,编译器不生成任何原子。的确,在两行之间有可能将侦听器设置为null。您可以使用synchronized来避免这种情况。

这里的同步太夸张了。在检查null:之前,只需复制成员变量

Listener mListener;
public void setListener(Listener listener){
   mListener=listener;
}
public void fooFunction(){
   ...
   ...
   Listener listener = mListener;
   if (listener!=null){
      listener.notifyFoo();
   }
}

是的,有可能。将您的fooFunction和setListener标记为同步,它应该使此代码成为多线程安全的

最新更新