注意:如果此等待和通知使用不正确的语法,请随时编辑/注释。
您的某个类的计算只能由不同的线程完成:
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"到处?
答案 0 :(得分:1)
我通常避免使用'this'进行同步。而不是使用synchronized(this),定义一个显式锁并与之同步。如果子类需要它,那么也可以让它们可用。 E.g。
class Foo {
protected final Object lock = new Object();
public Bar emptyBar() {
synchronized (lock) {
...
}
}
...
}
而不是this.notifyAll(),请使用lock.notifyAll();.
只要在同步(锁定)块中访问/更新您想要读/写的所有字段,您就可以放心,这些值是最新的。
答案 1 :(得分:0)
而不是同步整个实例。您只能同步方法。
Bar b; public synchronized Bar emptyBar(){//由线程#1调用("你的"线程)。 b = new Bar(); 返回b; }
而不是在Foo中添加synchronized
块。您可以在Bar中synchronize
方法更改对象的状态。