检查Java中的对象为空

时间:2017-01-04 08:39:44

标签: java multithreading design-patterns

我正在用Java编写代码,我正在创建一个对象并在两个不同的线程中访问它。我的第一个thread1线程在运行时调用了这个对象的一些公共方法。

final Thread thread1 = new Thread(){
    @Override
    public void run() {
        myObj.pubFunc1();
        myObj.puFunc2();
        myObj.pubFunc3();
    }
};

我有另一个帖子thread2可能会释放此对象并将其设置为null,如:

final Thread thread2 = new Thread(){
    @Override
    public void run() {
        myObj.release();
        myObj = null;
    }
};

我的问题是,我是否应该像null这样在每个陈述周围检查thread1

final Thread thread1 = new Thread(){
        @Override
        public void run() {
            if(myObj != null) {
                myObj.pubFunc1();
            }
            if(myObj != null) {
                myObj.pubFunc2();
            }
            if(myObj != null) {
                myObj.pubFunc3();
            }
        }
    };

或者只对所有陈述进行一次检查就够了吗?可能源于此的基本问题是我们对其进行空检查的对象周围存在锁定?如何处理这种情况。我应该使用什么设计模式来处理这种情况。

注意:我不希望这三个语句必须执行,我甚至不希望这三个语句形成一个原子单元。如果我正在执行操作的对象不为null,我只想执行一个操作。

1 个答案:

答案 0 :(得分:3)

您提出的设计存在缺陷。想象一下这个执行:

  • myObj = new MyObject();
  • 主题2:if (myObjec != null) =>好的,对象不是空的
  • 主题1:myObj.release(); myObj = null;
  • 主题2:myObj.pubFunc1(); =>繁荣,NPE。

我认为你只有两个选择:

  • 要么同步对myObj的访问,要使if / pubFunc调用原子
  • 或保存对象的本地副本 - 根据您的使用情况,这可能是也可能不可接受:

    public void run() {
      MyObject localObj = myObj;
      if (localObj != null { //NOTE: myObj may have been released
        localObj.pubFunc1();
        localObj.puFunc2();
        localObj.pubFunc3();
      }
    }
    

注意:我认为您了解可见性问题并且myObj已正确发布/同步。