新 Class 与 java 中锁定的新对象

new Class vs new Object for the lock in java

从 class 和对象创建的锁之间有什么区别吗?

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

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

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

java.awt 中,我看到了这段代码,我想知道 class AWTInvocationLock {} 而不仅仅是 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();
        }
    }

    //...
}

最好描述一下代码:

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();
        }
    }

锁对象引用是 逃离本地范围。 ref 存储在 InvocationEvent 对象中:

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

EventQueue 的调度线程正在侦听发布的事件对象。线程在每个事件上调用 dispatch() 方法。我没看过 在源代码中,但我猜 InvocationEvent.dispatch() 方法伪代码看起来像这样;

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

因此 EventQueue 分派线程在锁定对象上调用 notify(),这会从下一行的 wait() 调用中释放调用 invokeAndWait() 的线程。

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

AWTInvocationLock 是具有方法作用域的命名内部 class。我从来没有真正在野外见过一个。它是 真正 模糊的一部分 语言,一种我认识的人几乎没有人知道的语言。因此我永远不会使用它们,而且因为 Javadoc 甚至不识别这些并且不会为它们生成文档!

当调用锁定特定对象的方法时,它会锁定该对象的实例,直到方法调用完成。从这个角度来看,在何处实例化需要锁定的对象并不重要,只要它在方法调用期间保持相同的对象即可实现锁定结果

您的第一个代码段创建了一个在处理程序实例中定义的对象(class 上有方法 foo())。这意味着此处理程序将 不是 单线程的,因为它将始终锁定在您创建的锁定对象的 相同 实例上。

AWT 方法通过创建另一个独立于处理程序实例的锁对象来增强这一点。这意味着处理程序的单个实例可以处理不同 AWT 组件的多个事件,只要每个事件都由专用锁对象 (AWTInvocationLock()) 控制。