4

Is there any difference between a lock created from a class and from an object?

class AWTInvocationLock {}
Object lock = new AWTInvocationLock();

public void foo(){
    synchronized (lock) {
        // ...
    }
}

public Object lock = new Object();
public void bar(){
    synchronized (lock) {
        // ...
    }
}

In java.awt I see this code and I'm wondering about the idea of class AWTInvocationLock {} instead of just new Object()

static void invokeAndWait(Object source, Runnable runnable)
    throws InterruptedException, InvocationTargetException
{
    // ...

    class AWTInvocationLock {}
    Object lock = new AWTInvocationLock();

    InvocationEvent event =
        new InvocationEvent(source, runnable, lock, true);

    synchronized (lock) {
        Toolkit.getEventQueue().postEvent(event);
        while (!event.isDispatched()) {
            lock.wait();
        }
    }

    //...
}
Vitalii
  • 10,091
  • 18
  • 83
  • 151

2 Answers2

2

It's better to describe the code a bit:

class AWTInvocationLock {}
    Object lock = new AWTInvocationLock();

    InvocationEvent event =
        new InvocationEvent(source, runnable, lock, true);

    synchronized (lock) {
        Toolkit.getEventQueue().postEvent(event);
        while (!event.isDispatched()) {
            lock.wait();
        }
    }

The lock object reference is escaping the local scope. A ref is stored in the InvocationEvent object:

InvocationEvent event =
            new InvocationEvent(source, runnable, lock, true);

The EventQueue's dispatch thread is listening for posted Event objects. The thread invokes a dispatch() method on each event. I haven't looked at the source code, but I guess that the InvocationEvent.dispatch() method pseudo-code looks like this;

 1. synchronize(lock)
 2. runnable.run() -- store any exceptions to a "throwable" reference variable
 3. lock.notify()

So the EventQueue dispatch thread calls notify() on the lock object, which releases the thread that calls invokeAndWait() from the wait() call in the next line.

Is there any difference between a lock created from a class and from an object?

AWTInvocationLock is a named inner class with method scope. I've never actually seen one in the wild. Its a really obscure part of the language, and one that almost no one I know is aware of. I would never use one because of that, and because Javadoc doesn't even recognize these and won't generate documentation for them!

Mohsen
  • 4,536
  • 2
  • 27
  • 49
0

When a method that locks on a particular object is invoked, it locks on that instance of the object until the method invocation is complete. From that standpoint, it does not matter where you instantiate the object you need to lock on for as long as it stays the same object during the method's invocation to achieve the locking results.

Your first code segment creates a single object that is defined in the instance of the handler (the class that has method foo() on it). That means this handler will not single threaded because it will always lock on the same instance of the lock object you had created.

The AWT approach enhances this by creating another lock object which is independent of the handler instance. That means a single instance of the handler can process multiple events for different AWT components as long as each event is controlled by a dedicated lock object (AWTInvocationLock()).

Eslam Nawara
  • 645
  • 3
  • 8