Thursday, August 11, 2016

CuncurrentHashMap

The classic HashMap uses a function (the hash function) to determine which “bucket” it will store the key/value pair in. This is where the “hash” part of the class’s name comes from. This suggests a rather straightforward multithreaded generalization—instead of needing to lock the whole structure when making a change, it’s only necessary to lock the bucket that’s being altered.


The ConcurrentHashMap class also implements the ConcurrentMap interface, which contains some new methods to provide truly atomic functionality:
■ putIfAbsent()—Adds the key/value pair to the HashMap if the key isn’t already present.
■ remove()—Atomically removes the key/value pair only if the key is present and the value is equal to the current state.
■ replace()—The API provides two different forms of this method for atomic replacement in the HashMap.
As an example, you can replace the synchronized methods in listing with regular, unsynchronized access if you alter the HashMap called arrivalTime to be a ConcurrentHashMap as well. Notice the lack of locks in the following listing—there is no explicit synchronization at all.


Original HashMap
public class ExampleTimingNode implements SimpleMicroBlogNode {
 private final String identifier;
 private final Map<Update, Long> arrivalTime = new HashMap<>();

 public ExampleTimingNode(String identifier_) {
  identifier = identifier_;
 }

 public synchronized String getIdentifier() {
  return identifier;
 }

 public synchronized void propagateUpdate(Update update_) {
  long currentTime = System.currentTimeMillis();
  arrivalTime.put(update_, currentTime);
 }

 public synchronized boolean confirmUpdateReceived(Update update_) {
  Long timeRecvd = arrivalTime.get(update_);
  return timeRecvd != null;
 }
}

Replace with ConcurrentHashMap

import java.util.concurrent.ConcurrentHashMap;

public class ExampleMicroBlogTimingNode implements SimpleMicroBlogNode {

 private final ConcurrentHashMap<Update, Long> arrivalTime = new ConcurrentHashMap<Update, Long>();

 public void propagateUpdate(Update upd_) {
  arrivalTime.putIfAbsent(upd_, System.currentTimeMillis());
 }

 public boolean confirmUpdateReceived(Update upd_) {
  return arrivalTime.get(upd_) != null;
 }
}

No comments:

Post a Comment