[concurrency-interest] Locking a ConcurrentHashSet in a ConcurrentHasHMap

Mike Bean bean at alcatel-lucent.com
Wed Aug 6 20:10:21 EDT 2008


Experts,

I was wondering if anyone had some thoughts on how to avoid a lock to 
allow removal of a ConcurrentHashSet from a ConcurrentHashMap.  Context 
is an index manager with these two calls:

    public void index( Normal name, Value value, Entry entry )
    {
        if ( !m_indexingEnabled )
            return;

        ConcurrentHashMap<String,ConcurrentHashSet<Entry>> index = 
getIndex( name );
        if ( index != null )
        {
            String valueName = value.getAsString();
            while( true )
            {
                ConcurrentHashSet<Entry> set = index.get( valueName );
                if ( set == null )
                {
                    ConcurrentHashSet<Entry> newSet = new 
ConcurrentHashSet<Entry>();
                    newSet.add( entry );
                    if ( index.putIfAbsent( valueName, newSet ) == null )
                    {
                        break;
                    }
                }
                else
                {
                    synchronized ( set )  //!!! make sure we don't add 
entry to set while another thread removes empty set from index
                    {
                        if ( set.size() == 0 )
                        {
                            continue;
                        }
                        set.add( entry );
                        break;
                    }
                }
            }
        }
    }

    public void unindex( Normal name, Value value, Entry entry )
    {
        if ( !m_indexingEnabled )
            return;

        ConcurrentHashMap<String,ConcurrentHashSet<Entry>> index = 
getIndex( name );
        if ( index != null )
        {
            String valueName = value.getAsString();
            ConcurrentHashSet<Entry> set = index.get( valueName );
            if ( set != null )
            {
                synchronized ( set )  //!!! make sure we don't remove 
set from index while another thread adds entry to set
                {
                    set.remove( entry );
                    if ( set.size() == 0 )
                    {
                        index.remove( valueName, set );
                    }
                }
            }
        }
    }

Is there a better way to prevent one thread from updating the set while 
another thread is trying to remove the set from the map than the lock?.

I'm also concerned at the memory cost of a ConcurrentHashSet for a 
single reference to an Entry object but the indexing and unindexing 
entries gets more complex with the map containing an Entry or a 
ConcurrentHashSet of Entries.

Methods not shown from our index manager include queries that never fail 
as the map and set of entries change.

Thanks for all the work in this area,

Mike

-- 
Michael Bean (Mike)
Alcatel-Lucent
AAA Product Group
3461 Robin Ln, Ste 1
Cameron Park, CA 95682
Email: bean at alcatel-lucent.com
Phone: 530 672 7577
Fax: 530 676 3442



More information about the Concurrency-interest mailing list