Defining fields in concurrent environment

Developer87 :

I have two methods in my class, which will be executed within concurrent environment:

class Clazz {

  private int counter = 0;
  private volatile Map<..> map = new ConcurrentHashMap<>();
  private int[] array;

  public void concurrentMethod() {
    ...perform some actions with map...
  }

  public int nonConcurrentMethod() {
    ...reinitialize the map...change references...
    counter++;
    return array[counter];
  }

}

The question is following: assuming that nonConcurrentMethod is to be called by only one thread at a time, should I explicitly specify counter and array as a volatile fields? Make counter atomic?

My thoughts are it'd be better to insure that everything should work without glitches on a real production.

Karol Dowbecki :

Usually it's the entire class which has specific thread-safe semantics e.g. HashMap is not thread-safe while ConcurrentHashMap is. This is especially important if you are building a library, people might go around your design by calling nonConcurrentMethod() from multiple threads.

IMO if you can't split Clazz into two separate classes with different thread-safe semantics it would be prudent to make nonConcurrentMethod() thread-safe. In case nonConcurrentMetho() is called from multiple threads the performance will degrade but the correctness will be retained, hopefully avoiding hard to find bugs.

You can try an internal lock, which hopefully will not be too costly due to biased locking optimizing it when the lock is acquired from a single thread:

private final Object lock = new Object();

public int nonConcurrentMethod() {
  synchronized(lock) {
    ...reinitialize the map...change references...
    counter++;
    return array[counter];
  }
}

Make sure that at least one of the Clazz fields is final to ensure safe publication.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=83915&siteId=1