java - 观察者、可观察和可运行。为什么同步块(synchronized block)丢失了监视器?

标签 java observable observers synchronized-block

我正在尝试使用类作为观察者和可观察者。该类将作为线程运行。在 run() 方法中,线程将等待,并在获取事件后线程将被通知。有示例代码:

public class Runner {

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Controller c = new Controller();
        mt.addObserver(c);
        c.addObserver(mt);
        Thread t = new Thread(mt);
        t.start();
    }

}


public class MyThread extends Observable implements Observer, Runnable {

    static private Integer op = 0;

    public void run() {
      synchronized (this) {
        while (true) {
          op++;
          System.out.println(op + " Thread started");
          super.setChanged();
          super.notifyObservers(new Object());
          op++;
          System.out.println(op + " Thread send event");
          try {
            op++;
            System.out.println(op + " Thread wait");
            this.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }

    @Override
    public void update(Observable arg0, Object arg1) {
      op++;
      System.out.println(op + " Thread got event");
      synchronized (this) {
        op++;
        System.out.println(op + " We are in synchronized block!");
        this.notify();
      }
    }

}


public class Controller extends Observable implements Observer {

  public void update(Observable arg0, Object arg1) {
    System.out.println("Controller get and send event");
    super.setChanged();
    super.notifyObservers(new Object());
  }

}

得到的输出是:

1 Thread started
Controller get and send event
2 Thread got event
3 We are in synchronized block!
4 Thread send event
5 Thread wait

并且线程保持锁定状态。预期输出:

1 Thread started
Controller get and send event
2 Thread got event
3 Thread send event
4 Thread wait
5 We are in synchronized block!

出了什么问题?为什么我在监视器释放之前进入同步块(synchronized block)? 附:我有一个想法,问题是向 MyThread 对象添加观察者,我可能会向 Thread 对象添加观察者吗?但我怎么能做到这一点呢?

最佳答案

嗯,我认为您遇到的主要问题是 synchronized 关键字类似于可重入锁 ( http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html )。

这意味着,当您使用 MyThreadrun 方法时,您正在通知 Controller。然后,这个函数调用 MyThreadupdate,它进入 synchronized block (因为它是可重入的)并完成此方法。然后,Controller.update 方法返回,并且 MyThread.run 方法的其余部分继续执行,因此被困在 this.wait() 上。

关于java - 观察者、可观察和可运行。为什么同步块(synchronized block)丢失了监视器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15766056/

相关文章:

使用 javac 对同一 jar 成功编译后,java 在 jar 中找不到类

java - Apache 公共(public)数学 PolynomialSolver : how to get all roots?

Angular *ngIf 多次调用,使用异步管道和订阅

swift - 如何在 Firebase 3 和 Swift 3 中检索一次数据(停止观察者)

javascript - 如何对 HttpClient.get 返回的 Observable 实现副作用?

java - 如何在 LinearLayout 中创建小按钮,当您触摸其边缘时动态创建换行符?

java - 将字典放入具有重复单词的 HashMap 问题

javascript - 对 Mobx getDerivedStateFromProps 的误解

windows-phone-8 - 接收 2.1 : How to subscribe and observe on Dispatcher correctly

javascript - 如何在没有 _observer "magic"_(使用 vuecharts.js)的情况下将可变数量的数据集推送到图表数据?