View Javadoc

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&lt;Entity&gt;() {
34   *      public Entity call() {
35   *          // do find...
36   *      }
37   *  });
38   *}
39   *
40   *public void persist() {
41   *  getSynchronizer().runExclusively(new Callable&lt;Void&gt;() {
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  }