001 package com.hammurapi.util.concurrent;
002
003 import java.util.concurrent.Callable;
004
005 /**
006 * Callable which callInternal() method is invoked only once.
007 * @author Pavel Vlasov
008 *
009 * @param <T>
010 */
011 public abstract class OneOffCallable<T> implements Callable<T> {
012
013 private boolean hasRun;
014 private Exception exception;
015 private T result;
016
017 public synchronized T call() throws Exception {
018 if (!hasRun) {
019 try {
020 result = callInternal();
021 } catch (Exception e) {
022 exception = e;
023 } finally {
024 hasRun = true;
025 }
026 }
027
028 if (exception!=null) {
029 throw exception;
030 }
031 return result;
032 }
033
034 /**
035 * This method is invoked once by the call() method.
036 * @return
037 */
038 protected abstract T callInternal() throws Exception;
039
040 }