Domanda

Assume the following class:

public class MyClass {
  public synchronized void methodA() {
    //...code
  }
  public synchronized void methodB() {
    //...code
  }
  public synchronized void methodC() {
    //...code
  } 
}

Assume that none of the synchronized methods of MyClass call each other.

Do I assume correctly that 1, and only 1 Thread may have access to ANY of the code of MyClass at any given time? If, for example, a thread is executing methodA() on an instance of MyClass, I assume that no other Thread may call either methodB() or methodC() at this time, but will block until the execution of methodA() by the first thread is complete.

I want to clarify my understanding of Goetz, Java Concurrency in Practice (28), who states:

"Acquiring the lock associated with an object does not prevent other threads from accessing that object--the only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock."

In this particular case, I argue, Goetz' first statement is incorrect. MyClass employs implicit locking on each of its 3 methods--for each method the implicit lock is itself (this). Therefore, in this case, if a thread holds the implicit lock while executing methodA(), all other threads will be prevented from accessing any of the code on this object.

Do I understand method synchronization and implicit locking correctly?

Any perspectives are greatly appreciated!

È stato utile?

Soluzione

"Acquiring the lock associated with an object does not prevent other threads from accessing that object--the only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock."

Your three methods are declared as being synchronized. When one of those methods is invoked, like

MyClass instance = new MyClass();
instance.methodA();

the currently executing thread (call it A) will acquire that instance's monitor. No other thread will be able to acquire the same object's monitor until A has released it. Nothing prevents other threads from calling methods on that same object.

Say you had thread A doing

instance.methodA();

and thread B doing

instance.methodB();

Then, yes, thread B would have to wait for methodA to complete (ie. for thread A to release the lock on the object referenced by instance).

However, if thread A was doing

instance.methodA();

and thread B was doing

instance.toString();

thread B would not have to wait at all since toString() does nothing with the object's monitor.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top