使用wait-notify更新Java子类

时间:2014-03-30 14:49:58

标签: 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 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"到处?

2 个答案:

答案 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方法更改对象的状态。