为什么 wait() 和 notify() 不是特殊的class?
Why wait() and notify() are not in special class?
为什么 wait
、notify
和 notifyAll
方法放在 Object
中,而不是在一些分开的 class 中?
注意,这个问题不是把它们移到Thread
class,我只是想知道为什么它们会乱扔垃圾Object
,而不是一些新的Monitor
[=34] =].
我看到了这个想法的以下缺点:
- 我们将无法将我们的其他用途字段用作监视器。但这似乎符合模块化原则。
- 同步方法现在需要对生成的隐藏字段进行一些修改(例如在闭包中),因为
this
和 <MyClass>.class
成为无效监视器。
所以我们可以从每个对象中移除 5 个方法,但有点遗憾。还是不行?
因为每个对象都可以充当监视器。
真正的答案是这是一个错误,最终随着 Condition
class 的创建而得到承认,这正是您所期望的。 (尽管因为它是一个对象,所以您可能会不小心在其上调用 wait()
而不是 await()
,从而导致可笑的后果...)
除了您已经列出的内容之外,将监视器绑定到每个对象也使得不可能在 Java 中拥有真正不可变的对象。
所以你可以这样做,例如:
class A {
void foo() {
synchronized((Integer)42) {
...
}
}
}
class B {
void foo() {
synchronized((Integer)42) {
...
}
}
}
如果对象是不可变的,则每次为 42
返回相同的盒装整数应该不是问题。但它不是,它有一个可变状态:它的监视器,使这种同步成为可能。其中特别糟糕的是,您在两段代码之间创建了一个互斥量,而这两条代码表面上看起来是独立的。
1) Wait 和 notify 不仅仅是普通的方法或同步实用程序,更重要的是它们是 Java 中两个线程之间的通信机制。如果此机制无法通过任何 java 关键字(如同步)提供,对象 class 是使它们可用于每个对象的正确位置。记住同步和等待通知是两个不同的领域,不要混淆它们相同或相关。 synchronized是像race condition一样提供互斥保证线程安全Java class 而wait和notify是两个线程之间的通信机制
2) 锁在每个对象的基础上可用,这是在对象 class 而不是线程 class.
中声明等待和通知的另一个原因
3) 在 Java 中,为了进入代码的临界区,线程需要锁并等待锁,它们不知道哪些线程持有锁,它们只知道锁被某些线程持有线程,他们应该等待锁定而不是知道哪个线程在同步块内并要求他们释放锁定。这个类比适合在对象 class 上等待和通知,而不是在 Java.
中的线程
参考:http://javarevisited.blogspot.in/2012/02/why-wait-notify-and-notifyall-is.html
这样做的一个优点是您可以简单地在引用上同步而无需为其创建冗余监视器:
synchronized (myList) {
myList.add(0);
}
对
private final Object mySpecialMonitor = new Object();
syncronized(mySpecialMonitor) {
myList.add(0);
}
如果所有同步都在一个单独的 class 中,它将无法工作。
为什么 wait
、notify
和 notifyAll
方法放在 Object
中,而不是在一些分开的 class 中?
注意,这个问题不是把它们移到Thread
class,我只是想知道为什么它们会乱扔垃圾Object
,而不是一些新的Monitor
[=34] =].
我看到了这个想法的以下缺点:
- 我们将无法将我们的其他用途字段用作监视器。但这似乎符合模块化原则。
- 同步方法现在需要对生成的隐藏字段进行一些修改(例如在闭包中),因为
this
和<MyClass>.class
成为无效监视器。
所以我们可以从每个对象中移除 5 个方法,但有点遗憾。还是不行?
因为每个对象都可以充当监视器。
真正的答案是这是一个错误,最终随着 Condition
class 的创建而得到承认,这正是您所期望的。 (尽管因为它是一个对象,所以您可能会不小心在其上调用 wait()
而不是 await()
,从而导致可笑的后果...)
除了您已经列出的内容之外,将监视器绑定到每个对象也使得不可能在 Java 中拥有真正不可变的对象。
所以你可以这样做,例如:
class A {
void foo() {
synchronized((Integer)42) {
...
}
}
}
class B {
void foo() {
synchronized((Integer)42) {
...
}
}
}
如果对象是不可变的,则每次为 42
返回相同的盒装整数应该不是问题。但它不是,它有一个可变状态:它的监视器,使这种同步成为可能。其中特别糟糕的是,您在两段代码之间创建了一个互斥量,而这两条代码表面上看起来是独立的。
1) Wait 和 notify 不仅仅是普通的方法或同步实用程序,更重要的是它们是 Java 中两个线程之间的通信机制。如果此机制无法通过任何 java 关键字(如同步)提供,对象 class 是使它们可用于每个对象的正确位置。记住同步和等待通知是两个不同的领域,不要混淆它们相同或相关。 synchronized是像race condition一样提供互斥保证线程安全Java class 而wait和notify是两个线程之间的通信机制
2) 锁在每个对象的基础上可用,这是在对象 class 而不是线程 class.
中声明等待和通知的另一个原因3) 在 Java 中,为了进入代码的临界区,线程需要锁并等待锁,它们不知道哪些线程持有锁,它们只知道锁被某些线程持有线程,他们应该等待锁定而不是知道哪个线程在同步块内并要求他们释放锁定。这个类比适合在对象 class 上等待和通知,而不是在 Java.
中的线程参考:http://javarevisited.blogspot.in/2012/02/why-wait-notify-and-notifyall-is.html
这样做的一个优点是您可以简单地在引用上同步而无需为其创建冗余监视器:
synchronized (myList) {
myList.add(0);
}
对
private final Object mySpecialMonitor = new Object();
syncronized(mySpecialMonitor) {
myList.add(0);
}
如果所有同步都在一个单独的 class 中,它将无法工作。