2014-01-17 24 views
1

我遇到了不正确地同步访问映射的代码 - 但我分析了非同步代码的影响,它不是我所期望的。已同步和未同步的作家哈希映射 - 结果不如预期

本质上,代码有多个写入线程写入HashMap perAccountMap_,此代码已正确同步。

但是存在由一个单独的线程,其读取地图和复位它称为一个代码段:

// Unsynchronized code :(- called from a single thread - reads Map and resets it 
    public static Map<PDKey, PData> copyAndClearPerAccountMap() 
    { 
     Map<PDKey, PData> copyMap = perAccountMap_; 
     perAccountMap_ = new HashMap<PDKey, PData>(); 
     return copyMap; 
    } 

现在,我能够独立地验证正被上述上复制的地图中的内容一些多核心盒子。 直觉上我会期望上面的copyMap低估Map中的条目 - 也就是说,因为它不同步,所以其他同步写入器线程插入到Map中对于获取它的副本的单个线程不一定是可见的。 但是,反过来似乎是这样的 - 上面的副本似乎一贯有约。多1%的条目。 我可以修复不同步的代码,但我不明白我观察到的结果。

+2

我不明白。您不复制地图,而是复制参考。你能改述你所看到的行为吗?或者张贴能够重现它的代码? –

+0

对不起我的坏 - 是复制当然参考 –

回答

2

我可以提供的最佳理论是作家线程在更改后仍然在短时间内写入原始映射。如果perAccountMap_不易变,这可能会发生,因为copyAndClear方法所做的更改不会立即被其他线程看到。

+0

是的,这是合理的。现在,非同步线程每15分钟(ScheduledExecutorService)创建一个新的Map,而同步的线程每秒运行多次。但是新的Map没有写入原始的Map。 –

+0

它不会写入原始地图,但是不同的写入器线程可能会同时写入原始地图和新地图。 –