1 4 package com.tc.util.concurrent; 5 6 import com.tc.exception.TCInternalError; 7 import com.tc.logging.TCLogger; 8 import com.tc.logging.TCLogging; 9 import com.tc.util.TCTimeoutException; 10 11 17 public class TCFuture { 18 private static final TCLogger logger = TCLogging.getLogger(TCFuture.class); 19 private volatile boolean set; 20 private volatile boolean cancel; 21 private volatile boolean timedOut; 22 private volatile Throwable exception; 23 private volatile Object value; 24 private final Object lock; 25 26 public TCFuture() { 27 this(null); 28 } 29 30 public TCFuture(Object lock) { 31 this.lock = lock == null ? this : lock; 32 cancel = false; 33 value = null; 34 exception = null; 35 set = false; 36 } 37 38 44 public Object get() throws InterruptedException , TCExceptionResultException { 45 try { 46 return get(0); 47 } catch (TCTimeoutException e) { 48 throw new TCInternalError("Timeout not supposed to happen here"); 49 } 50 } 51 52 63 public Object get(long timeout) throws InterruptedException , TCTimeoutException, TCExceptionResultException { 64 return get(timeout, true); 65 } 66 67 80 public Object get(long timeout, boolean flagIfTimedOut) throws InterruptedException , TCTimeoutException, 81 TCExceptionResultException { 82 synchronized (this.lock) { 83 if (cancel) { throw new InterruptedException ("Future already cancelled"); } 84 85 while (!set) { 86 if (timeout < 0) { throw new TCTimeoutException("Timeout of " + timeout + " milliseconds occurred"); } 87 88 lock.wait(timeout); 89 90 if (cancel) { throw new InterruptedException ("Future was cancelled while waiting"); } 91 92 if ((!set) && (timeout != 0)) { 93 this.timedOut = flagIfTimedOut; 94 throw new TCTimeoutException("Timeout of " + timeout + " milliseconds occured"); 95 } 96 } 97 98 if (exception == null) { 99 return value; 100 } else if (exception != null) { 101 throw new TCExceptionResultException(exception); 103 } 104 105 throw new TCInternalError("Neither exception nor value set"); 106 } 107 } 108 109 116 public void setException(Throwable ex) { 117 if (ex == null) { throw new IllegalArgumentException ("exception result cannot be null"); } 118 119 synchronized (this.lock) { 120 if (cancel) { 121 logger.warn("Exception result set in future after it was cancelled"); 122 return; 123 } 124 125 if (set) { throw new IllegalStateException ("Future result already set"); } 126 127 set = true; 128 this.exception = ex; 129 this.lock.notifyAll(); 130 } 131 } 132 133 140 public void set(Object value) { 141 synchronized (this.lock) { 142 143 if (cancel) { 144 logger.warn("Value set in future after it was cancelled"); 145 return; 146 } 147 148 if (set) { throw new IllegalStateException ("Value already set"); } 149 150 set = true; 151 this.value = value; 152 this.lock.notifyAll(); 153 } 154 } 155 156 161 public void cancel() { 162 synchronized (this.lock) { 163 if (set) { 164 logger.warn("Attempt to cancel an already set future value"); 165 } 166 167 cancel = true; 168 this.lock.notifyAll(); 169 } 170 } 171 172 175 public boolean timedOut() { 176 return this.timedOut; 177 } 178 179 } | Popular Tags |