1 | package com.hammurapi.common.concurrent; |
2 | |
3 | import java.util.concurrent.Callable; |
4 | |
5 | /** |
6 | * Callable which callInternal() method is invoked only once. |
7 | * @author Pavel Vlasov |
8 | * |
9 | * @param <T> |
10 | */ |
11 | public abstract class OneOffCallable<T> implements Callable<T> { |
12 | |
13 | private boolean hasRun; |
14 | private Exception exception; |
15 | private T result; |
16 | |
17 | public synchronized T call() throws Exception { |
18 | if (!hasRun) { |
19 | try { |
20 | result = callInternal(); |
21 | } catch (Exception e) { |
22 | exception = e; |
23 | } finally { |
24 | hasRun = true; |
25 | } |
26 | } |
27 | |
28 | if (exception!=null) { |
29 | throw exception; |
30 | } |
31 | return result; |
32 | } |
33 | |
34 | /** |
35 | * This method is invoked once by the call() method. |
36 | * @return |
37 | */ |
38 | protected abstract T callInternal() throws Exception; |
39 | |
40 | } |