164 * for (;;) { 165 * try { 166 * lock.acquire(); 167 * try { 168 * if (other.lock.attempt(100)) { 169 * try { 170 * long t = value; 171 * value = other.value; 172 * other.value = t; 173 * return; 174 * } 175 * finally { other.lock.release(); } 176 * } 177 * } 178 * finally { lock.release(); } 179 * } 180 * catch (InterruptedException ex) { return; } 181 * } 182 * } 183 * } 184 *</pre> 185 * <p> 186 * Here is an even fancier version, that uses lock re-ordering 187 * upon conflict: 188 * <pre> 189 * class Cell { 190 * long value; 191 * Sync lock = ...; 192 * private static boolean trySwap(Cell a, Cell b) { 193 * a.lock.acquire(); 194 * try { 195 * if (!b.lock.attempt(0)) 196 * return false; 197 * try { 198 * long t = a.value; 199 * a.value = b.value; 200 * b.value = t; 201 * return true; 202 * } 203 * finally { other.lock.release(); } 204 * } 205 * finally { lock.release(); } 206 * return false; 207 * } 208 * 209 * void swapValue(Cell other) { 210 * try { 211 * while (!trySwap(this, other) && 212 * !tryswap(other, this)) 213 * Thread.sleep(1); 214 * } 215 * catch (InterruptedException ex) { return; } 216 * } 217 *} 218 *</pre> 219 * <p> 220 * Interruptions are in general handled as early as possible. 221 * Normally, InterruptionExceptions are thrown 222 * in acquire and attempt(msec) if interruption 223 * is detected upon entry to the method, as well as in any 224 * later context surrounding waits. 225 * However, interruption status is ignored in release(); 226 * <p> 227 * Timed versions of attempt report failure via return value. 228 * If so desired, you can transform such constructions to use exception 229 * throws via 230 * <pre> 231 * if (!c.attempt(timeval)) throw new TimeoutException(timeval); 232 * </pre> 233 * <p> 234 * The TimoutSync wrapper class can be used to automate such usages. 235 * <p> 236 * All time values are expressed in milliseconds as longs, which have a maximum 237 * value of Long.MAX_VALUE, or almost 300,000 centuries. It is not 238 * known whether JVMs actually deal correctly with such extreme values. 239 * For convenience, some useful time values are defined as static constants. 240 * <p> 241 * All implementations of the three Sync methods guarantee to 242 * somehow employ Java <code>synchronized</code> methods or blocks, 243 * and so entail the memory operations described in JLS 244 * chapter 17 which ensure that variables are loaded and flushed 245 * within before/after constructions. 246 * <p> 247 * Syncs may also be used in spinlock constructions. Although 248 * it is normally best to just use acquire(), various forms 249 * of busy waits can be implemented. For a simple example 250 * (but one that would probably never be preferable to using acquire()): 251 * <pre> 252 * class X { 253 * Sync lock = ... 254 * void spinUntilAcquired() throws InterruptedException { 255 * // Two phase. 256 * // First spin without pausing. 257 * int purespins = 10; 258 * for (int i = 0; i < purespins; ++i) { 259 * if (lock.attempt(0)) 260 * return true; 261 * } 262 * // Second phase - use timed waits 263 * long waitTime = 1; // 1 millisecond 264 * for (;;) { 265 * if (lock.attempt(waitTime)) 266 * return true; 267 * else 268 * waitTime = waitTime * 3 / 2 + 1; // increase 50% 269 * } 270 * } 271 * } 272 * </pre> 273 * <p> 274 * In addition pure synchronization control, Syncs 275 * may be useful in any context requiring before/after methods. 276 * For example, you can use an ObservableSync 277 * (perhaps as part of a LayeredSync) in order to obtain callbacks 278 * before and after each method invocation for a given class. 279 * 280 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] 281 **/ 282 283 284 public interface Sync { 285 286 /** 287 * Wait (possibly forever) until successful passage. 288 * Fail only upon interuption. Interruptions always result in 289 * `clean' failures. On failure, you can be sure that it has not 290 * been acquired, and that no 291 * corresponding release should be performed. Conversely, 292 * a normal return guarantees that the acquire was successful. 293 **/ 294 295 public void acquire() throws InterruptedException; 296 297 /** 298 * Wait at most msecs to pass; report whether passed. 299 * <p> 300 * The method has best-effort semantics: | 164 * for (;;) { 165 * try { 166 * lock.acquire(); 167 * try { 168 * if (other.lock.attempt(100)) { 169 * try { 170 * long t = value; 171 * value = other.value; 172 * other.value = t; 173 * return; 174 * } 175 * finally { other.lock.release(); } 176 * } 177 * } 178 * finally { lock.release(); } 179 * } 180 * catch (InterruptedException ex) { return; } 181 * } 182 * } 183 * } 184 * </pre> 185 * <p> 186 * Here is an even fancier version, that uses lock re-ordering 187 * upon conflict: 188 * <pre>{@code 189 * class Cell { 190 * long value; 191 * Sync lock = ...; 192 * private static boolean trySwap(Cell a, Cell b) { 193 * a.lock.acquire(); 194 * try { 195 * if (!b.lock.attempt(0)) 196 * return false; 197 * try { 198 * long t = a.value; 199 * a.value = b.value; 200 * b.value = t; 201 * return true; 202 * } 203 * finally { other.lock.release(); } 204 * } 205 * finally { lock.release(); } 206 * return false; 207 * } 208 * 209 * void swapValue(Cell other) { 210 * try { 211 * while (!trySwap(this, other) && 212 * !tryswap(other, this)) 213 * Thread.sleep(1); 214 * } 215 * catch (InterruptedException ex) { return; } 216 * } 217 * } 218 * }</pre> 219 * <p> 220 * Interruptions are in general handled as early as possible. 221 * Normally, InterruptionExceptions are thrown 222 * in acquire and attempt(msec) if interruption 223 * is detected upon entry to the method, as well as in any 224 * later context surrounding waits. 225 * However, interruption status is ignored in release(); 226 * <p> 227 * Timed versions of attempt report failure via return value. 228 * If so desired, you can transform such constructions to use exception 229 * throws via 230 * <pre> 231 * if (!c.attempt(timeval)) throw new TimeoutException(timeval); 232 * </pre> 233 * <p> 234 * The TimoutSync wrapper class can be used to automate such usages. 235 * <p> 236 * All time values are expressed in milliseconds as longs, which have a maximum 237 * value of Long.MAX_VALUE, or almost 300,000 centuries. It is not 238 * known whether JVMs actually deal correctly with such extreme values. 239 * For convenience, some useful time values are defined as static constants. 240 * <p> 241 * All implementations of the three Sync methods guarantee to 242 * somehow employ Java <code>synchronized</code> methods or blocks, 243 * and so entail the memory operations described in JLS 244 * chapter 17 which ensure that variables are loaded and flushed 245 * within before/after constructions. 246 * <p> 247 * Syncs may also be used in spinlock constructions. Although 248 * it is normally best to just use acquire(), various forms 249 * of busy waits can be implemented. For a simple example 250 * (but one that would probably never be preferable to using acquire()): 251 * <pre>{@code 252 * class X { 253 * Sync lock = ... 254 * void spinUntilAcquired() throws InterruptedException { 255 * // Two phase. 256 * // First spin without pausing. 257 * int purespins = 10; 258 * for (int i = 0; i < purespins; ++i) { 259 * if (lock.attempt(0)) 260 * return true; 261 * } 262 * // Second phase - use timed waits 263 * long waitTime = 1; // 1 millisecond 264 * for (;;) { 265 * if (lock.attempt(waitTime)) 266 * return true; 267 * else 268 * waitTime = waitTime * 3 / 2 + 1; // increase 50% 269 * } 270 * } 271 * } 272 * }</pre> 273 * <p> 274 * In addition pure synchronization control, Syncs 275 * may be useful in any context requiring before/after methods. 276 * For example, you can use an ObservableSync 277 * (perhaps as part of a LayeredSync) in order to obtain callbacks 278 * before and after each method invocation for a given class. 279 * 280 * [<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] 281 **/ 282 283 284 public interface Sync { 285 286 /** 287 * Wait (possibly forever) until successful passage. 288 * Fail only upon interuption. Interruptions always result in 289 * `clean' failures. On failure, you can be sure that it has not 290 * been acquired, and that no 291 * corresponding release should be performed. Conversely, 292 * a normal return guarantees that the acquire was successful. 293 **/ 294 295 public void acquire() throws InterruptedException; 296 297 /** 298 * Wait at most msecs to pass; report whether passed. 299 * <p> 300 * The method has best-effort semantics: |