Geek
Geek

Reputation: 27219

Reentrant locks and alien methods called from synchronized regions (Effective Java item)

From Effective Java (Chapter 10 Concurrency)

Suppose you were to invoke an alien method from within a synchronized region while the invariant protected by the synchronized region was temporarily invalid. Because locks in the Java programming language are reentrant, such calls won’t deadlock

Now look at the following code :

// Broken - invokes alien method from synchronized block!
public class ObservableSet<E> extends ForwardingSet<E> {
  public ObservableSet(Set<E> set) {
    super(set);
  }

  private final List<SetObserver<E>> observers = new ArrayList<SetObserver<E>>();

  private void notifyElementAdded(E element) {
    synchronized (observers) {
      for (SetObserver<E> observer : observers)
        observer.alienMethod(this, element);
    }
  }
}

So consider SetObservers and ObservableSet are two independently written classes and they reside in different package and thus alienMethod() of SetObserveris alien to the ObservableSet class. Now say observers is not in a consistent state when alienMethod gets called. So where is the question of reentrant locks coming here ? The reentrancy will only come into question if the alien method also synchronizes on the same lock ie `observers' but this doesn't seem to be the case here or am I missing something here ?

Upvotes: 2

Views: 739

Answers (1)

Marko Topolnik
Marko Topolnik

Reputation: 200296

And what happens if the alienMethod causes an event to get fired, which ends up re-entering that same notifyElementAdded method? This is a real-world hazard, I've been bitten by it once.

In this particular case you must make a safe copy of your list and run through it in peace.

Upvotes: 6

Related Questions