new Class vs new Object锁定Java

时间:2018-12-25 22:16:18

标签: java multithreading locking

从类和对象创建的锁之间有区别吗?

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

    //...
}

2 个答案:

答案 0 :(得分:2)

最好稍微描述一下代码:

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

锁对象引用为 转义本地范围。引用存储在InvocationEvent对象中:

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

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

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

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

  

从类和对象创建的锁之间有区别吗?

AWTInvocationLock是具有方法范围的命名内部类。我从未真正在野外见过。这是真正的模糊部分 语言,几乎没有一个我知道的语言。因此,我永远都不会使用它,因为Javadoc甚至无法识别它们,也不会为它们生成文档!

答案 1 :(得分:0)

调用锁定特定对象的方法时,它将锁定该对象的实例,直到方法调用完成。从这个角度来看,只要在方法调用期间保持锁定结果的相同对象,您实例化需要锁定的对象的位置就无关紧要。

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

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