Вопрос

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!

Это было полезно?

Решение

"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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top