Future の静的リストを保持しようとしていますが、後で、進行中の Future を cancel() または notify() します。これらの Future に関連付けられている Callable クラスには wait() が含まれているため、続行するには外部ソースからそれぞれに通知する必要があります。ただし、呼び出し可能オブジェクトが待機ステートメントを通過しないため、notify() への私の呼び出しは無視されているようです。Futures のリストを持つクラスは次のようになります。
private static Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();
ExecutorService taskExecutor;
public void doStuff() {
taskExecutor = Executors.newCachedThreadPool();
// loop inifinitely - external processes will modify the conditions within
while(!shutItDown) {
if (<condition1>) {
// condition 1 dictates the kick-off of a new callable
Future<Object> future = taskExecutor.submit(new MyCallable(id));
results.put(id, future);
}
else if (<condition2>) {
// condition 2 represents a callable in a wait status needs
// to be notified
Future<Object> future = results.get(uid);
if (future != null) {
synchronized(future) {
future.notify(); // this doesn't have the desired effect!
}
}
}
}
}
Callable クラスは今のところ単なるモックアップで、次のようになります。
public class MyCallable implements Callable<Object> {
private String id;
public MyCallable(String id) {
this.id = id;
}
@Override
public Object call() throws Exception {
try {
// do some work here, then wait on outside notification
synchronized(this) {
this.wait(); // never gets past here!!!
}
// do some other work here, once this has been notified
}
catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
notify() メソッドが呼び出されますが、効果がないようです。Future のオブジェクト参照は有効に見えます (つまり、ローカル変数 "future" は、静的リストに保存されている Future の参照と一致します)。
ここでは、同時実行の基本的な概念が欠けている可能性がありますが、条件 2 が満たされると、Callable が wait() 呼び出しを通過することを期待していました。
notify() の代わりに cancel() を使用すると、runnable が中断され、予想どおり InterruptedException が発生することに注意してください。