org.linkedin.util-core/src/main/java/org/linkedin/util/concurrent/ThreadControl.java
public void unblock(Object key, Object value)
  {
    if(log.isDebugEnabled())
      log.debug(LangUtils.shortIdentityString(this) + ".unblock(" + key + ", " + value + ")");
    
    _lock.lock();
    try
    {
      try
      {
        waitForBlock(key);
      }
      catch(InterruptedException e)
      {
        throw new RuntimeException(e);
      }
      catch(TimeoutException e)
      {
        throw new RuntimeException(e);
      }

      _waitingForBlock.remove(key);
      _waitingForUnblock.put(key, value);
      _unblockCondition.signalAll();
    }
    finally
    {
      _lock.unlock();
    }
  }
public void unblock(Object key, Object value)
  {
    if(log.isDebugEnabled())
      log.debug(LangUtils.shortIdentityString(this) + ".unblock(" + key + ", " + value + ")");
    
    _lock.lock();
    try
    {
      try
      {
        waitForBlock(key);
      }
      catch(InterruptedException e)
      {
        throw new RuntimeException(e);
      }
      catch(TimeoutException e)
      {
        throw new RuntimeException(e);
      }

      _waitingForBlock.remove(key);
      _waitingForUnblock.put(key, value);
      _unblockCondition.signalAll();
    }
    finally
    {
      _lock.unlock();
    }
  }
This method is called from one thread while another is going to call <code>block</code>. It
is basically a synchronization point as this method will block until
<code>block</code> is called and will then release the thread who called <code>block</code>
in the first place.

@param key the same key used in <code>block</code>
@param value the value that will be returned by <code>block</code>