001package com.hammurapi.common.concurrent; 002 003import java.util.concurrent.Callable; 004 005/** 006 * Callable which callInternal() method is invoked only once. 007 * @author Pavel Vlasov 008 * 009 * @param <T> 010 */ 011public 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}