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 }