1

I am writing my code in Java where I am creating an object and and accessing it in two different threads. My first thread1 thread calls some public methods on this object at runtime.

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

I have another thread thread2 which might release this object and set it to nulllike:

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

My question is if I should put check for null around each statement in my thread1 like this?

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

OR only one check around all the statements is enough? The basic question that might originate from this is there is a lock around the object on which we have made a null check? How to handle this situation. What design pattern should I use to handle this situation.

NOTE: I do not want the three statements to be necessarily executed and I even do no want that the three statements form an atomic unit. I just want to perform an operation if the object I am performing the operation on is not null.

1
  • 3
    If the object can become null asynchronously, you must check for that, and it must also either be volatile or read and written only in synchronized blocks or methods. This is not a 'design pattern', it is just common sense, arising out of the JLS. Commented Jan 4, 2017 at 8:45

1 Answer 1

3

The design your propose is flawed. Imagine this execution:

  • myObj = new MyObject();
  • Thread 2: if (myObjec != null) => all good, object is not null
  • Thread 1: myObj.release(); myObj = null;
  • Thread 2: myObj.pubFunc1(); => Boom, NPE.

I think you only have 2 options:

  • either you synchronize the accesses to myObj to make the if/pubFunc calls atomic
  • or you save a local copy of the object - this may or may not be acceptable depending on your use case:

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

Note: I assume that you are aware of visibility issues and that myObj is properly published/synchronized.

Sign up to request clarification or add additional context in comments.

4 Comments

I understand the meaning of an object being synchronized. What exactly do you mean by 'published'. Also, I assume that when you say 'visibility issues', these are related to private, public, protected and package level visibilities right?
@Swapnil no I meant visibility across threads. For example I suppose that either myObj is fully created before the threads start or it is volatile. And I also assumed that the various methods (pubFunc1 etc.) are thread safe.
So what I understand till now is that you propose to have the null check and all the three function call inside a synchronizedmy(Obj) (which would need to be surrounded by a null check also). And when you say that the methods are thread safe, you mean they have a keyword synchronized with their declarations right?
That's a bit simplistic and what you describe may or may not work. Thread safety and synchronization is all about the details so it's hard to say based on a high level description.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.