Учитывая, что вы не возражаете против устаревшего вызова EJB, продолжающегося на сервере, почему бы не позволить вызывающему потоку завершить «естественным образом», но отказаться от результата, потому что его вызов был заменен другим потоком?У меня нет времени, чтобы предоставить пример реализации, но вы можете обнаружить, что вы получаете некоторый пробег с Future
s и связанными классами параллелизма Java.
Edit
В дополнение к этому, вы можете найти что-то вроде этого, но это кажется мне счастливым, и я уверен, что есть более элегантные решения.
В вызывающем потоке (возможно, метод onclick длякнопка):
AsynchronousResultManager.registerRequest("UNIQUE_IDENTIFIER", runnableExecuteRequest);
registerRequest
будет делать что-то вроде:
registerClick(String id, Runnable execution) {
AtomicReference ref = executions.get(id); //executions is a Map<String, AtomicReference> created as a a computing map by Guava MapMaker
execution.setReference(ref); //so that the Runnable has a reference to it later
ref.set(execution); //this will overwrite an existing reference to a previous invocation.
//here you need to actually kick off your thread in whatever way works best for you
}
runnable
, который выполняет запрос, будет подклассом:
public abstract class RequestRunnable implements Runnable {
private AtomicReference ref;
public void run() {
doRunInternal(); //actually go off and do the request to the J2EE server
if (this == ref.get()) { //ie if the current runnable is the same as in the reference, we can proceed to actually dispatch the result
dispatchResult(); //this method would do something like add a runnable to the SwingWorkerThread
}
}
protected abstract void doRunInternal();
protected abstract void dispatchResult();
public void setReference(AtomicReference ref) {
this.ref = ref;
}
}
Это, вероятно, приведет к сбою и сгоранию, но, надеюсь, оно укажет вам направление расследования ...