从类和对象创建的锁之间有区别吗?
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();
}
}
//...
}
答案 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()
)控制即可。