我有两个类,其中一个实现可运行的,这一个从网站获取数据,然后将其放入ConcurrentHashMap中,另一个稍后再获取此数据。第一类成功获取数据并将其放入地图中,我可以看到地图已满,但是当另一类尝试获取数据时,键在这里,但值变为空。
public class KAuctionThread extends KObject implements Runnable
{
...
KParserMapBaseClass.getLiveStreamMap( this.getThreadConfig( ).getDataSource( ) ).put( realTimeActionKey, di ) ;
...
}
这行将数据放入下面的地图中
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 ;
}
}
当第一堂课把数据放在eclipse表达式中时,我可以看到它:
{B2BOtoNet={someurl=com.lib1k.cmap.agent2.KDownloadInfo@622d2710}}
但是当另一个阶级试图达到
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 ;
}
地图变成这样:
{B2BOtoNet={}}
没有其他可放入或获取数据的类
最佳答案
没有可复制的例子很难说。可能是此方法不是原子方法,并且您将覆盖映射中以前创建的实例。
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;
}
您可以更简洁,更原子地执行相同的操作:
public static ConcurrentHashMap<String, KDownloadInfo> getLiveStreamMap(String dataSource)
{
return liveStream.computeIfAbsent(dataSource, k -> new ConcurrentHashMap<>());
}