final Node<K,V> find(int h,Object k){
  if (k != null) {
    for (Node<K,V> e=first; e != null; ) {
      int s;
      K ek;
      if (((s=lockState) & (WAITER | WRITER)) != 0) {
        if (e.hash == h && ((ek=e.key) == k || (ek != null && k.equals(ek))))         return e;
        e=e.next;
      }
 else       if (U.compareAndSwapInt(this,LOCKSTATE,s,s + READER)) {
        TreeNode<K,V> r, p;
        try {
          p=((r=root) == null ? null : r.findTreeNode(h,k,null));
        }
  finally {
          Thread w;
          if (U.getAndAddInt(this,LOCKSTATE,-READER) == (READER | WAITER) && (w=waiter) != null)           LockSupport.unpark(w);
        }
        return p;
      }
    }
  }
  return null;
}

final Node < K , V > find ( int h , Object k ) { if ( k != null ) { for ( Node < K , V > e = first ; e != null ; ) { int s ; K ek ; if ( ( ( s = lockState ) & ( WAITER | WRITER ) ) != 0 ) { if ( e . hash == h && ( ( ek = e . key ) == k || ( ek != null && k . equals ( ek ) ) ) ) return e ; e = e . next ; } else if ( U . compareAndSwapInt ( this , LOCKSTATE , s , s + READER ) ) { TreeNode < K , V > r , p ; try { p = ( ( r = root ) == null ? null : r . findTreeNode ( h , k , null ) ) ; } finally { Thread w ; if ( U . getAndAddInt ( this , LOCKSTATE , - READER ) == ( READER | WAITER ) && ( w = waiter ) != null ) LockSupport . unpark ( w ) ; } return p ; } } } return null ; }
returns matching node or null if none . tries to search using tree comparisons from root , but continues linear search when lock not available .
