在java中不使用static关键字从回调方法获取变量



class MyApplication观察到另一个类,并且自身也被观察到。问题是"update"方法对布尔值replyOne和replyTwo的更新对"run"方法不可见。我希望运行MyApplication类的多个副本,因此不希望使用static关键字。有没有办法让run方法在不使用static关键字修改布尔值的情况下查看布尔值的更改?

观察到的和MyApplication类由另一个类启动,如下所示:

final ServerOne firstServer = new ServerOne();
    MyApplication appOne = new MyApplication();
    // subscribe the observers to the observed - eberybody watches each other
    firstServer.addObserver(appOne);
    appOne.addObserver(firstServer);
    // start the  threads 
    Thread firstServerThread = new Thread(firstServer,"firstServer");
    firstServerThread.start();
    Thread thread3 = new Thread(appOne, "appOne");
    thread3.start();

MyApplication类的代码如下:

public class MyApplication extends Observable implements Observer, Runnable {
    private String resp, response;
    private long timeTaken;
    private boolean replyOne,replyTwo;

    @Override
    public void update(Observable observable, Object arg) {
        timeTaken = (System.nanoTime() - ((Long) arg).longValue()) / 1000;
        if (observable instanceof ServerOne) {
            //process ObservableCLass1 update here
            System.out.println("App Thread " + Thread.currentThread().getName() + " received update from serverOne in " + timeTaken + " microSecs");
            this.replyOne = true;
        } else if (observable instanceof ServerTwo) {
            System.out.println("App Thread " + Thread.currentThread().getName() + " received update from serverTwo in " + timeTaken + " microSecs");
            this.replyTwo = true;
        }
        timeTaken = ((Long) arg).longValue();
        setChanged();
        notifyObservers(timeTaken);
        clearChanged();
    }
    public void run() {
        this.replyOne = false;
        this.replyTwo = false;
        while (!this.replyOne || !this.replyTwo) {
            // wait until the observer has set both the reply flags
            if (this.replyOne) {
                System.out.println("Reply one True ");
                setChanged();
                notifyObservers(new String("app Calling after update from serverOne "));
                this.replyOne = false;
            }
            if (this.replyTwo) {
                System.out.println("Reply two True ");
                setChanged();
                notifyObservers(new String("app Calling after update from serverTwo "));
                this.replyTwo = false;
            }
        }
    }
}

存在多个问题。首先,看看你的run方法:

this.replyOne = false;
this.replyTwo = false;
while (!this.replyOne && this.replyTwo) {

首先将两个变量都设置为false,然后如果replyTwotrue,则进入循环,这是不太可能发生的。很可能,你的意思是:while (!this.replyOne && !this.replyTwo)

但整个结构看起来很可疑。很明显,这里缺少的等待代码应该在一个循环中等待它至少一个标志变成true,但为什么通知也在循环中?run方法应在何种情况下再次等待,何时退出?

也许你过于简单化了。预期的代码可能是这样的:

this.replyOne = false;
this.replyTwo = false;
while(!endCondition) {
    while (!this.replyOne && !this.replyTwo) {
        // wait until the observer has set both the reply flags
    }
    if (this.replyOne) {
        System.out.println("Reply one True ");
        setChanged();
        notifyObservers(new String("app Calling after update from serverOne "));
        this.replyOne = false;
    }
    if (this.replyTwo) {
        System.out.println("Reply two True ");
        setChanged();
        notifyObservers(new String("app Calling after update from serverTwo "));
        this.replyTwo = false;
    }
}

我假设您将一个正确的线程安全构造放在注释中"等待观察者设置了两个回复标志"的位置。否则就没有内存可见性的保证,换句话说,即使另一个线程修改了其中一个变量,这个循环也可能无限运行。

带有包含replyOnereplyTwo的额外事件类对象的notifyObservers将是经典方式。
public class ReplyEvent {
    public boolean replyOne;
    ...
}

ReplyEvent evt = new ReplyEvent();
evt.message = "...";
evt.replyOne = replyOne;
...
notifyObservers(evt);

最新更新