简体   繁体   中英

ConcurrentHashMap values become empty

I have two classes one of which implements runnable, this one gets the data from a website then puts it into a ConcurrentHashMap and the other gets this data later. First class successfully gets the data and puts it into the map, I can see the map is full but when the other class tries to get data, keys are here but values become empty.

public class KAuctionThread extends KObject implements Runnable 
{
...
    KParserMapBaseClass.getLiveStreamMap( this.getThreadConfig( ).getDataSource( ) ).put( realTimeActionKey, di ) ;
...
}

This line puts the data into the map below

public abstract class KParserMapBaseClass extends KObject implements Callable<KDownloadInfo>
{
public static ConcurrentHashMap<String, ConcurrentHashMap<String, KDownloadInfo>> liveStream = new ConcurrentHashMap<>( ) ;// !!!
...
...
public static ConcurrentHashMap<String, KDownloadInfo> getLiveStreamMap( String dataSource )
{
    ConcurrentHashMap<String, KDownloadInfo> dataSourceMap = KParserMapBaseClass.liveStream.get( dataSource ) ;

    if( dataSourceMap == null )
    {
        dataSourceMap = new ConcurrentHashMap<String, KDownloadInfo>( ) ;

        KParserMapBaseClass.liveStream.put( dataSource, dataSourceMap ) ;
    }

    return dataSourceMap ;
}
}

I can see the data in eclipse expression when first class puts it:

{B2BOtoNet={someurl=com.lib1k.cmap.agent2.KDownloadInfo@622d2710}}

But when the other class tries to reach

ConcurrentHashMap<String, KDownloadInfo> map = KParserMapBaseClass.getLiveStreamMap( di.dataSource ) ;
    if( map != null && map.size( ) > 0 )
    {
        String key = map.keySet( ).iterator( ).next( ) ;

        KDownloadInfo rtdi = map.remove( key ) ;

        return rtdi ;
    }

Map becomes like that:

{B2BOtoNet={}}

There is no other class that puts or gets the data

It's very difficult to say without a reproducible example. It could be that this method is not atomic and that you are overriding instances in the map that have already been created before.

public static ConcurrentHashMap<String, KDownloadInfo> getLiveStreamMap(String dataSource)
{
    ConcurrentHashMap<String, KDownloadInfo> dataSourceMap = KParserMapBaseClass.liveStream.get(dataSource) ;

    if (dataSourceMap == null)
    {
        dataSourceMap = new ConcurrentHashMap<String, KDownloadInfo>();
        KParserMapBaseClass.liveStream.put(dataSource, dataSourceMap);
    }
    return dataSourceMap;
}

You can do the same thing more concisely and atomically:

public static ConcurrentHashMap<String, KDownloadInfo> getLiveStreamMap(String dataSource)
{
    return liveStream.computeIfAbsent(dataSource, k -> new ConcurrentHashMap<>());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM