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