Это не совсем то, посмотрите там надо явно выбирать готовые futures. А я говорю о том, чтобы получил Future и поручил ему самому в том потоке, где он "посчитается" доделать кой-какую работенку.
Я правильно понял, что требуется ограничить время выполнения метода? Т.е. если метод invoke(Object) выполняется дольше X милисекунд, то он должен просто прерываться?
Если нужно действительно это, то есть вот такая идея:
Future не может делать то же самое, поскольку Thread, который выполняет сам Callable может и не join до конца работы JVM. там скорее будет что-то типа wait(Object, long), но скорее всего с использованием java.util.concurrent
Если public Object invoke(Object in) throws MyException объявлен в интерфейсе или его допускается модифицировать, я бы проявил недюженное эстетство и предложил использовать
TimeLimiter.newProxy из библиотеки Guava от Google.
Comments 20
Reply
void addListener(FutureListener listener); //можно вызывать много раз
public interface FutureListener extends EventListener {
void operationComplete(Future future) throws Exception;
}
чтобы:
Future f = ...
f.addListener(new FutureListener(){
public void operationComplete(Future future) throws Exception {
проверили успех, записали в БД/и тп и тд
}
});
Эдакий fire-and-forget
Reply
Reply
А я говорю о том, чтобы получил Future и поручил ему самому в том потоке, где он "посчитается" доделать кой-какую работенку.
Reply
а вот неправильно и некрасиво:
public Object invoke( final Object arg, long timeoutMs ) throws InterruptedException
{
final Object result[]=new Object[1];
synchronized( result )
{
Thread th = new Thread(){
public void run(){
result[0] = invoke( arg );
if ( result[ 0 ] == null ) result[0]=result;
synchronized( result )
{
result.notify();
}
}
};
th.start();
result.wait( timeoutMs );
th.interrupt();
// th.stop(); // if you know what you are doing
}
if ( result[ 0 ] == null ) throw new InterruptedException();
return result[ 0 ] == result ? null: result[ 0 ];
}
Reply
Если нужно действительно это, то есть вот такая идея:
public void invoke(Object arg) throws MyException {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return in + " invoke";
}
public void timedInvoke(final Object arg, long millis) {
Thread thread = new Thread(
new Runnable() {
public void run() {
try {
invoke(obj);
} catch (MyException ex) {
ex.printStackTrace();
}
}
}
);
thread.start();
try {
thread.join(millis);
} catch (InterruptedException ignore) {}
if (thread.isAlive()) {
thread.interrupt();
}
}
Reply
Reply
Reply
Reply
Reply
public Object invoke(Object in) throws MyException
объявлен в интерфейсе или его допускается модифицировать,
я бы проявил недюженное эстетство и предложил использовать
TimeLimiter.newProxy из библиотеки Guava от Google.
Против Гугла кто ж попробует возбухнуть ;-)
Reply
Leave a comment