Garikai
Garikai

Reputation: 425

How to prevent method from being executed concurrently by different threads within the same class instance

Say I have two threads, both started from a given class instance, A. The threads have to execute a method from the same instance, but one at a time. I tried making the method synchronized but apparently it applies when there are different instances trying to call the method (from what I understood; pardon me if I'm wrong).

So how do I go about accomplishing this, preferably in a standard or recommended manner?

EDIT: Here's the relevant code:

public class A {
.
.
.
  public void method1(){

    ExecutorService threadObject = Executors.newSingleThreadExecutor();
            threadObject.execute(new Runnable(){
                @Override
                public void run() {
                    try {
                        while (someCondition) {
                          //Here's one invocation
                          someObject = readObject();
                        }
                    }
                    catch (IOException | ClassNotFoundException ex) {}
                }
            });

    //Here's the other invocation
    while(someCondition){
      someObject = readObject();
    }
  }

  //Here's the synchronized method
  private synchronized SomeClass readObject() throws IOException, ClassNotFoundException{
          return (SomeClass) incomingResponses.readObject();
  }

  //Main method to instantiate the class
  public static void main(String ... args) {
    A = new A();
    A.method1();
  }
}

I'm still not sure what I'm doing wrong.

Upvotes: 0

Views: 70

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27115

synchronized methods are a shortcut. IMO, you should learn to do it the long way before you start using the shortcut:

If you have this:

class A {
    synchronized SomeType myMethod(...) {
        doSomeStuff(...);
        ...
        return someThing;
    }
}

That is a shortcut for writing a method declaration with a top-level synchronized statement:

class A {
    SomeType myMethod(...) {
        synchronized (this) {
            doSomeStuff(...);
            ...
            return someThing;
        }
    }
}

IMO, you should learn how to use synchronized statements first, and then only use synchronized methods when you have a better understanding of how synchronized statements work.

Upvotes: 1

NiVeR
NiVeR

Reputation: 9786

Your statement is wrong. Quoting the relevant example from documentation:

  • First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
  • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

So, synchrinzed keyword applied on method will not allow concurrent invocations of the method on a particular object instance.

Upvotes: 0

Related Questions