code: public void releaseSharedLock(int requestId) throws NoSharedLockException
    {
      if (tc.isEntryEnabled()) Tr.entry(tc, "releaseSharedLock",new Object[]{this,new Integer(requestId)});
  
      Thread currentThread = Thread.currentThread();
      int newValue = 0;
  
      synchronized(this)
      {
        Integer count = (Integer)_sharedThreads.get(currentThread);
  
        if (count == null)
        {
          if (tc.isEntryEnabled()) Tr.exit(tc, "releaseSharedLock", "NoSharedLockException");
          throw new NoSharedLockException();
        }
  
        newValue = count.intValue()-1;
  
        if (newValue > 0)
        {
          count = new Integer(newValue);
          _sharedThreads.put(currentThread,count);
        }
        else
        {
          count = null;
          _sharedThreads.remove(currentThread);
        }
  
        // If this thread no longer holds any shared locks then inform those waiting of this
        // fact.
        if (count == null)
        {
          this.notifyAll();
        }
      }
  
      if (tc.isDebugEnabled())
      {
        int countValue = 0;
        Integer count = (Integer)_sharedThreads.get(currentThread); 
        
        if (count != null) countValue = count.intValue();
        
        Tr.debug(tc, "Count: " + count);          
      }
      
      if (tc.isEntryEnabled()) Tr.exit(tc, "releaseSharedLock");
    }
docs: Releases a single shared lock from thread.
  
  @exception NoSharedLockException The caller does not hold a shared lock to release
  
  @param requestId The 'identifier' of the lock requester. This is used ONLY for
  trace output. It should be used to 'pair up' get/set pairs in
  the code.