我正在尝试使用类作为观察者和可观察者。该类将作为线程运行。在 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 )。
这意味着,当您使用 MyThread
的 run
方法时,您正在通知 Controller
。然后,这个函数调用 MyThread
的 update
,它进入 synchronized
block (因为它是可重入的)并完成此方法。然后,Controller.update
方法返回,并且 MyThread.run
方法的其余部分继续执行,因此被困在 this.wait()
上。
关于java - 观察者、可观察和可运行。为什么同步块(synchronized block)丢失了监视器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15766056/