我在使用线程时遇到观察者模式和死锁问题。
package observerDeadLock;
import java.util.Observable;
public class MyModel extends Observable {
Integer foo;
public MyModel() {
foo = 0;
}
public void changeStatus(Integer newStatus) {
foo = newStatus;
notifyObservers(newStatus);
}
}
package observerDeadLock;
public class Job extends Thread {
public MyModel model;
public Job(MyModel model) {
super();
this.model = model;
}
public void run() {
prepareJob();
runMyJob();
}
private void runMyJob() {
// Some stuff
Integer choice = 1;
if (choice == 3) {
return;
}
else if (choice == 2) {
return;
}
else if (choice == 1) {
model.changeStatus(123); // Set a particalar status that MyController receive as wrong!
// PROBLEM: The Controller listen the changeStatus(123) of notifyObserver of MyModel and call a join() because I want the thread join and quit()
return; // <<- NEVER EXECUTED! join(timeout) isn't the solution IHMO...s
}
return;
}
private void prepareJob() {
// Do some stuff
}
package observerDeadLock;
import java.util.Observable;
import java.util.Observer;
public class MyController implements Observer {
private Job myJob;
private MyModel model;
public MyController() {
}
public void startJob() {
model = new MyModel();
model.addObserver(this);
myJob = new Job(model);
myJob.start();
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof MyModel) {
if (((Integer) arg) == 1) {
// do other stuff
}
else if (((Integer) arg) == 2) {
// do other stuff
}
else if (((Integer) arg) == 123) { // 123 => Wrong state for myController, so must stop Job
// Stop myJob!!!
try {
//myJob.join(timeout); // isn' the solution IHMO
myJob.join(); // PROBLEM HERE!!! In job, the "return" statment is locked in changeStatus() -> myModel.notifyobserver() that lock here in JOIN();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
我能做些什么来解决这个问题?我想使用 Thread.join() 而不是 Thread.interrupt() 是一种不好的做法...... 建议?
谢谢!
最佳答案
您显然正在尝试 join()
当前线程(如果将 myJob.join()
替换为 System. out.println( Thread.currentThread() )
),这不是一个好主意,因为线程将永远卡住,或者直到其他人从外部中断它。
不用 join()
,只需调用 interrupt()
,这没什么可耻的。 (虽然它是否会产生任何影响取决于 runMyJob()
中的其他内容)
更新:我只能假设您为简洁起见编辑了部分代码,但如果 MyController
在遇到退出值 123
时真的什么都不做,而不是停止更新线程,那么整个构造就没有必要了。您应该简单地从 runMyJob()
方法返回而不进行任何设置,线程将正常停止。
关于Java:线程中的 NotifyObserver 和 DeadLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9875780/