0

私は奇妙に設計されたライブラリを使用しています。このコードには基本的にTaskオブジェクトonComplete()onfail()メソッドがあり、これらのメソッドは両方とも無効であるため、それらの内部で return を使用できません。

タスク内で更新された外部変数を使用 しようとonComplete()しましたonfail()

mytask.wait();
return value; 

タスクの完了を待ってから値を返すつもりですが、

java.lang.IllegalMonitorStateException: object not locked by thread before wait()

私が何かを試してみると

while(!mytask.isComplete(){}

メソッドに完了を強制的に待機させる

アプリが完全にフリーズする

タスクの完了時に値を正しく取得するにはどうすればよいですか?

4

2 に答える 2

1

java.lang.IllegalMonitorStateException: オブジェクトが wait() の前にスレッドによってロックされていない

あなたは近づいていますが、いくつかの同期が欠けています。するwait()か、ブロックnotify()にいる必要があります。synchronized

何らかの値を返すタスクを書きたい場合は、次のようにします。結果をフィールドに格納し、synchronized onComplete()またはonFail()メソッド内のそのフィールドを更新します。その後、呼び出し元のスレッドはwaitForResult()メソッドを使用して、終了したらそれを返すことができます。

public class MyTask implements Task {
    private String result;
    public synchronized void onComplete() {
        result = "it worked";
        // this is allowed because the method is synchronized
        notify();
    }
    public synchronized void onFail() {
        result = "it failed";
        // this is allowed because the method is synchronized
        notify();
    }
    public synchronized String waitForResult() {
        // a while loop is a good pattern because of spurious wakeups
        // also, it's important to realize that the job might have already
        // finished so we should always test it _before_ we wait
        while (result == null) {
            wait();
        }
        return result;
    }
}

すべてが終了することをテストしているスレッドは、次のことを行う必要があります。

String result = myTask.waitForResult();

お役に立てれば。

于 2018-05-19T16:12:39.223 に答える