Задача на собеседовании

Feb 05, 2010 23:32


Пример задачи достаточно необычной, которую мне задали.
sample task + my solution )

Leave a comment

Comments 20

lexicore February 5 2010, 22:15:46 UTC
Тоже сразу о Future подумал.

Reply

magicprinc February 6 2010, 10:19:15 UTC
А вообще это мне одному кажется, что Future не хватает метода

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

magicprinc February 8 2010, 10:54:14 UTC
Это не совсем то, посмотрите там надо явно выбирать готовые futures.
А я говорю о том, чтобы получил Future и поручил ему самому в том потоке, где он "посчитается" доделать кой-какую работенку.

Reply


sassa_nf February 5 2010, 22:23:43 UTC
зачот. с Future правильно и красиво.

а вот неправильно и некрасиво:

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


jabberwack February 5 2010, 22:38:48 UTC
Я правильно понял, что требуется ограничить время выполнения метода? Т.е. если метод invoke(Object) выполняется дольше X милисекунд, то он должен просто прерываться?

Если нужно действительно это, то есть вот такая идея:

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

valyakol February 6 2010, 04:30:00 UTC
О, хороший пример. Этот ответ и ожидался, так как нужно было написать пример на бумаге.

Reply

jabberwack February 6 2010, 16:13:48 UTC
А вот мне интересно - вариант с Future, если смотреть изнутри, то же самое делает? Или там какие-то инновационные технологии использованы?

Reply

sassa_nf February 8 2010, 10:14:59 UTC
Future не может делать то же самое, поскольку Thread, который выполняет сам Callable может и не join до конца работы JVM. там скорее будет что-то типа wait(Object, long), но скорее всего с использованием java.util.concurrent

Reply


magicprinc February 6 2010, 08:18:08 UTC
Здорово, вы помните про новые классы и их методы ( ... )

Reply


magicprinc February 6 2010, 08:32:01 UTC
Если
public Object invoke(Object in) throws MyException
объявлен в интерфейсе или его допускается модифицировать,
я бы проявил недюженное эстетство и предложил использовать

TimeLimiter.newProxy из библиотеки Guava от Google.

Против Гугла кто ж попробует возбухнуть ;-)

Reply


Leave a comment

Up