当两个线程尝试修改/访问Concurrent HashMap中的相同键时会发生什么?

时间:2016-04-03 22:03:51

标签: java multithreading hashmap concurrenthashmap

我读到了关于hashMap以及它与hashtable的不同之处。与哈希表一样,完整对象被锁定,而在并发哈希映射的情况下,只有一部分被锁定。我的问题是当两个线程在samme时间尝试访问相应的值时,会发生什么情况。

让我们说

    <html>
<head>
    <script src="http://maps.googleapis.com/maps/api/js?key=MyKey"></script>
    <script>
        function initialize() {
            var mapProp = {
                center: new google.maps.LatLng(44, -80), //this google.maps call is fine
                zoom: 5,
                mapTypeId: google.maps.MapTypeId.ROADMAP //this one works too
            };
            var ClownMap = new google.maps.Map(document.getElementById("googleMap"), mapProp);

            {
                @for (var i=1; i < 4; i++){
                            var latitude = 45+i;
                            var longitude = -81+i;
                            var markerPosition = new google.maps.LatLng(latitude, longitude); //This line gives an error
                            var marker = new google.maps.Marker({ position: markerPosition}); } //Error here too
                }
             marker.setMap(ClownMap);
        }
        google.maps.event.addDomListener(window, 'load', initialize);
    </script>
</head>

<body>
    <div id="googleMap" style="width:960px;height:600px;"></div>
</body>

线程1:尝试读取mp.get(1)。

线程2:尝试写入/修改mp.put(1,“Hi”)。

那么线程1可以读取什么值?

编辑:我的意思是ConcurrentHashMap。

1 个答案:

答案 0 :(得分:2)

  

线程1可以读取什么值?

它将读取两个可能的值,

  • 由于尚未设置值,因此获得null
  • 它获得了线程2设置的值。

这可能听起来不是很多,但你应该注意到HashMap可能会进入无限循环并且永远不会返回,这很糟糕。

ConcurrentHashMap真正有用的地方是像putIfAbsent这样的操作。为了在线程之间传递工作,队列是更好的选择。

ConcurrentMap<Integer, BlockingQueue<String>> map = ...

线程1

String value = map.putIfAbsent(1, k -> new BlockingQueue<>()).take();

线程2

map.putIfAbsent(1, k -> new BlockingQueue<>()).offer("Hi");

在这种情况下,线程1将阻塞,直到线程2添加了值。注意:此值仅可用一次。