使用wait notify更新Java子类
注意:如果此等待和通知使用了不正确的语法,请随意编辑/评论 您有一个类,该类的计算仅由不同的线程完成:使用wait notify更新Java子类,java,concurrency,wait,notify,Java,Concurrency,Wait,Notify,注意:如果此等待和通知使用了不正确的语法,请随意编辑/评论 您有一个类,该类的计算仅由不同的线程完成: class Foo{ public Foo() { //so thread 2 can know about us. So much for design patterns. synchronized(GlobalStuff) {GlobalStuff.threadpool.add(this);} } Bar b; public Bar em
class Foo{
public Foo() {
//so thread 2 can know about us. So much for design patterns.
synchronized(GlobalStuff) {GlobalStuff.threadpool.add(this);}
}
Bar b;
public Bar emptyBar() { //called by thread #1 ("your" thread).
synchronized(this) {
b = new Bar();
return b;
}
}
public void makeTest() { //Thread #2 periodically runs this block of code.
synchronized(this) {
if (b==null) {return;} //do nothing if it is still null.
if (b.hasBeenMadeIntoExam();) {return;} //do nothing if it is done already.
b.makeMeAnAnnoyingExam();
....
this.notifyAll(); //do we even need the "this"?
}
}
}
以下是您等待它的方式:
//thread 1 runs this block of code.
Foo fooey = new Foo();
Bar b = fooey.emptyBar();
while( b.equals(fooey.emptyBar()) ) { //some statement to check whether it is done or not
try { //mandatory try catch statements to keep Java verbose.
fooey.makeTest();
fooey.wait(); //wait, and fooey will free us when it calls notifyAll()
} catch (InterruptedException ex) {}
}
.... //more code that depends on the exam being made.
我担心的是b的字段不是易失性的(即使我们将b更改为易失性),所以当线程2更新它们时,它们不会立即出现在线程1中。请记住,同步和通知并不“深入”,因此它们不会仔细地更新所有子类的状态。我需要担心吗?有没有一种方法可以解决这个问题,而不用手动在每个地方粘贴“volatile”?而不是同步整个实例。您只能同步方法 b栏; 公共同步条emptyBar(){//由线程#1(“您的”线程)调用。 b=新杆(); 返回b; }
而不是在Foo中添加
synchronized
块。您可以同步
条中更改对象状态的方法。我通常避免使用“this”进行同步。不要使用synchronized(这个),而是定义一个显式锁并根据该锁进行同步。如果子类需要它,那么也让它们可以使用它。例如
class Foo {
protected final Object lock = new Object();
public Bar emptyBar() {
synchronized (lock) {
...
}
}
...
}
使用lock.notifyAll();,而不是这个.notifyAll()
只要要读/写的所有字段都在同步(锁定)块中被访问/更新,您就可以确信这些值是最新的。很难解释为什么多线程代码甚至无法编译。在提出问题之前,请注意代码。是的,这种方式具有更少的阻塞,因此具有更高的性能(尽管在我的真实版本中没有太大帮助)。我的方法可以按原样工作吗?你不能通过使用它作为锁对象来同步“整个类”。那时它只是另一把锁。同步较小的代码总是更好。为什么不使用这个呢?子类无法获得它?@tgkprog“this”可能会允许意外的同步作用域爬行,因为外部代码可以同步(fooInstance),这增加了在处理同步的多个监视器时引入死锁的可能性。此外,它还使得以后更容易将锁定impl从同步更改为读写锁定等其他操作,而无需担心您可能无法查看的外部代码(尤其是库)。