1 /* 2 * Copyright 2006-2010 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package net.sourceforge.domian.util.concurrent.locks; 17 18 import java.util.concurrent.Callable; 19 20 /** 21 * Interface for synchronizing arbitrary blocks of code within a JVM process. 22 * These blocks of code must be expressed either as {@link Runnable}s, or as {@link Callable}s. 23 * <p/> 24 * All blocks of code synchronized by this class either run in <i>concurrent</i>, or <i>exclusive mode</i>. 25 * <i>Concurrent mode</i> means that the blocks will run as normal, possibly in a concurrent manner. 26 * They will, however, be gracefully preemptied by blocks running in <i>exclusive mode</i>. 27 * {@link Runnable}s and {@link Callable}s running in exclusive mode always waits for all other concurrent-mode blocks to finish, 28 * then runs exclusively, queuing up all other blocks until it has finished. 29 * <p/> 30 * Usage example:<br/> 31 * <pre> 32 *public Entity find(final Specification spec) { 33 * return getSynchronizer().runConcurrently(new Callable<Entity>() { 34 * public Entity call() { 35 * // do find... 36 * } 37 * }); 38 *} 39 * 40 *public void persist() { 41 * getSynchronizer().runExclusively(new Callable<Void>() { 42 * public Void call() { 43 * // do persist... 44 * return null; 45 * } 46 * }); 47 *}</pre> 48 * 49 * @author Eirik Torske 50 * @since 0.4 51 */ 52 public interface Synchronizer { 53 54 public enum MODE { 55 CONCURRENT, EXCLUSIVE 56 } 57 58 /** 59 * Runs a {@link Runnable} in a concurrent manner. 60 * 61 * @param runnable the runnable to invoke concurrently, managed by this class 62 */ 63 <R extends Runnable> void runConcurrently(R runnable); 64 65 /** 66 * Calls a {@link Callable} in a concurrent manner. 67 * 68 * @param callable the callable to invoke concurrently, managed by this class 69 * @return the {@link Callable}'s return value, or <code>null</code> if no return value 70 */ 71 <T, C extends Callable<T>> T callConcurrently(C callable); 72 73 /** 74 * Runs a {@link Runnable} in an exclusive manner. 75 * Firstly, it will wait for all other exclusive {@link Runnable}s and {@link Callable}s to finish, if any. 76 * Then it will wait for already running concurrent {@link Runnable}s and {@link Callable}s to finish, if any. 77 * Finally it will run, queuing up all other {@link Runnable}s and {@link Callable}s managed by the same {@link Synchronizer} instance. 78 * When done, all queues are released. 79 * 80 * @param runnable the runnable to invoke exclusively, managed by this class 81 */ 82 <R extends Runnable> void runExclusively(R runnable); 83 84 /** 85 * Calls a {@link Callable} in an exclusive manner. 86 * Firstly, it will wait for all other exclusive {@link Runnable}s and {@link Callable}s to finish, if any. 87 * Then it will wait for already running concurrent {@link Runnable}s and {@link Callable}s to finish, if any. 88 * Finally it will run, queuing up all other {@link Runnable}s and {@link Callable}s managed by the same {@link Synchronizer} instance. 89 * When done, all queues are released. 90 * 91 * @param callable the callable to invoke exclusively, managed by this class 92 * @return the {@link Callable}'s return value, or <code>null</code> if no return value 93 */ 94 <T, C extends Callable<T>> T callExclusively(C callable); 95 }