View Javadoc

1   package com.atlassian.util.concurrent;
2   
3   import static com.atlassian.util.concurrent.Functions.fromSupplier;
4   import static com.atlassian.util.concurrent.LockManagers.Manager.createManager;
5   import static com.atlassian.util.concurrent.ManagedLocks.lockFactory;
6   import static com.atlassian.util.concurrent.ManagedLocks.managedLockFactory;
7   import static com.atlassian.util.concurrent.WeakMemoizer.weakMemoizer;
8   
9   import java.util.concurrent.Callable;
10  import java.util.concurrent.locks.Lock;
11  
12  /**
13   * @deprecated since 0.0.7 use {@link ManagedLocks} instead
14   */
15  @Deprecated
16  // /CLOVER:OFF
17  public class LockManagers {
18  
19      /**
20       * Convenience method that simply calls {@link #weakLockManager(Function)}
21       * with the identity function. So all inputs map directly to an individual
22       * lock.
23       * 
24       * @param <T> the type of the thing used to look up locks
25       * @deprecated use {@link ManagedLocks#weakManagedLockFactory()} instead.
26       */
27      @Deprecated
28      public static <T> LockManager<T> weakLockManager() {
29          return weakLockManager(Functions.<T> identity());
30      }
31  
32      /**
33       * Get a {@link LockManager} that is used to perform operations under a
34       * particular lock. The specific lock chosen is decided by the supplied
35       * striping function. The particular {@link Lock} is resolved using a
36       * {@link Function} that resolves to a descriptor used to look up a Lock
37       * instance. This allows for a finite set of locks to be used even if the
38       * set of T is essentially unbounded.
39       * <p>
40       * For instance:
41       * 
42       * <pre>
43       * LockManager&lt;Identifiable, Integer&gt; manager = LockManagers.weakLockManager(new Function&lt;Identifiable, Integer&gt;() {
44       *     Integer get(Identifiable thing) {
45       *         return thing.getId() % 16;
46       *     }
47       * };
48       * </pre>
49       * 
50       * uses only 16 possible locks as the function returns the modulo 16 of the
51       * thing's id.
52       * 
53       * @param <T> the type of the thing used to look up locks
54       * @param <D> the type used to map lock instances
55       * @param stripeFunction to convert Ts to Ds.
56       * @return a new {@link LockManager} instance that stores created
57       * {@link Lock} instances with weak references.
58       * @deprecated use {@link ManagedLocks#weakManagedLockFactory(Function)}
59       * instead.
60       */
61      @Deprecated
62      public static <T, D> LockManager<T> weakLockManager(final Function<T, D> stripeFunction) {
63          final Function<D, ManagedLock> lockFactory = fromSupplier(managedLockFactory(lockFactory()));
64          final WeakMemoizer<D, ManagedLock> memoizer = weakMemoizer(lockFactory);
65          return createManager(memoizer, stripeFunction);
66      }
67  
68      /**
69       * Default implementation of {@link LockManager}
70       * 
71       * @param <T> the input type
72       * @param <D> the type used for the internal lock resolution.
73       */
74      static class Manager<T, D> implements LockManager<T> {
75          static final <T, D> Manager<T, D> createManager(final Function<D, ManagedLock> lockFactory, final Function<T, D> stripeFunction) {
76              return new Manager<T, D>(lockFactory, stripeFunction);
77          }
78  
79          private final Function<D, ManagedLock> lockFactory;
80          private final Function<T, D> stripeFunction;
81  
82          Manager(final Function<D, ManagedLock> lockFactory, final Function<T, D> stripeFunction) {
83              this.lockFactory = lockFactory;
84              this.stripeFunction = stripeFunction;
85          }
86  
87          public <R> R withLock(final T descriptor, final Supplier<R> supplier) {
88              return lockFactory.get(stripeFunction.get(descriptor)).withLock(supplier);
89          }
90  
91          public <R> R withLock(final T descriptor, final Callable<R> callable) throws Exception {
92              return lockFactory.get(stripeFunction.get(descriptor)).withLock(callable);
93          }
94  
95          public void withLock(final T descriptor, final Runnable runnable) {
96              lockFactory.get(stripeFunction.get(descriptor)).withLock(runnable);
97          }
98      }
99  }
100 // /CLOVER:ON