View Javadoc

1   package com.atlassian.cache.impl;
2   
3   import java.util.concurrent.TimeUnit;
4   import java.util.concurrent.locks.AbstractQueuedSynchronizer;
5   
6   /**
7    * A useful synchronization construct for ensuring the correct behaviour of cache implementations.
8    * <p>
9    * The one-shot latch is initially held by the thread that creates it and must be explicitly
10   * released by it.
11   * </p>
12   *
13   * @since v2.4.5
14   */
15  public class OneShotLatch
16  {
17      private final Sync sync = new Sync();
18  
19      public boolean isHeldByCurrentThread()
20      {
21          return sync.isHeldByCurrentThread();
22      }
23  
24      public void release()
25      {
26          sync.release(0);
27      }
28  
29      public void await()
30      {
31          sync.acquireShared(0);
32      }
33  
34      public boolean await(long timeout, TimeUnit unit) throws InterruptedException
35      {
36          return sync.tryAcquireSharedNanos(0, unit.toNanos(timeout));
37      }
38  
39      @Override
40      public String toString()
41      {
42          return "OneShotLatch[sync=" + sync + ']';
43      }
44  
45  
46  
47      static class Sync extends AbstractQueuedSynchronizer
48      {
49          private static final int STATE_UNAVAILABLE = -1;
50          private static final int STATE_RELEASED = 1;
51  
52          Sync()
53          {
54              setState(STATE_UNAVAILABLE);
55              setExclusiveOwnerThread(Thread.currentThread());
56          }
57  
58          boolean isHeldByCurrentThread()
59          {
60              return getExclusiveOwnerThread() == Thread.currentThread();
61          }
62  
63          @Override
64          protected boolean tryRelease(int ignored)
65          {
66              if (!isHeldByCurrentThread())
67              {
68                  throw new IllegalMonitorStateException(toString());
69              }
70  
71              setExclusiveOwnerThread(null);
72              setState(STATE_RELEASED);
73              return true;
74          }
75  
76          @Override
77          protected int tryAcquireShared(int ignored)
78          {
79              final int state = getState();
80              if (state == STATE_UNAVAILABLE && isHeldByCurrentThread())
81              {
82                  throw new IllegalMonitorStateException(toString());
83              }
84              return state;
85          }
86  
87          @Override
88          public String toString()
89          {
90              return "Sync[state=" + getState() + "; owner=" + getExclusiveOwnerThread() + ']';
91          }
92      }
93  }