简体   繁体   English

使用等待通知进行Java子类更新

[英]Java sub-class updateting with wait-notify

Note: feel free to edit/comment if this wait and notify uses incorrect syntax. 注意:如果此等待和通知使用不正确的语法,请随时进行编辑/注释。

You have a class that has a calculation that is only done by a different thread: 您有一个类,该类的计算只能由其他线程完成:

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"?
      }
   }
}

Here is how you wait for it: 这是您的等待方式:

//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.

My concern is that b's fields are not volatile (even if we changed b to be volatile), so when thread #2 updates them, they don't immediately appear for thread 1. Remember, synchronizing and notify are not "deep" so they don't meticulously update the state of all sub-classes. 我担心的是b的字段不是可变的(即使我们将b更改为可变的),因此当线程2更新它们时,它们不会立即出现在线程1中。请记住,同步和通知不是“深”的,因此它们不要一味地更新所有子类的状态。 Do I need to worry about it? 我需要担心吗? Is there a way to fix this without manually sticking "volatile" everywhere? 有没有一种方法可以解决此问题,而无需在各处手动添加“ volatile”?

I generally avoid using 'this' for synchronized. 我通常避免使用“ this”进行同步。 Instead of using synchronized(this), define an explicit lock and synchronize against that. 而不是使用sync(this),而是定义一个显式锁并对此进行同步。 If subclasses need it, then make it available to them as well. 如果子类需要它,则也可以将其提供给他们。 Eg 例如

class Foo {

  protected final Object lock = new Object();

  public Bar emptyBar() {
    synchronized (lock) { 
      ...
    }
  }

  ...

}

And instead of this.notifyAll(), use lock.notifyAll();. 而不是this.notifyAll(),请使用lock.notifyAll();。

So long as all fields that you want to read/write are accessed/updated within the synchronized(lock) blocks you can rest assured that the values are the most recent. 只要您要在Synchronized(lock)块内访问/更新要读取/写入的所有字段,就可以放心这些值是最新的。

Instead of synchronizing whole instance. 而不是同步整个实例。 You can synchronize only method. 您只能同步方法。

Bar b; 酒吧b; public synchronized Bar emptyBar() { //called by thread #1 ("your" thread). 公共同步Bar emptyBar(){//由线程1(“您的”线程)调用。 b = new Bar(); b =新的Bar(); return b; 返回b; } }

Instead of making adding synchronized blocks in Foo. 而不是在Foo中添加synchronized块。 You can synchronize methods in Bar which changes state of object. 您可以在Bar中synchronize更改对象状态的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM