Do I need an AtomicInteger inside a synchronized (anyObject) block?

I want to keep track of the position within a queue that changes within a block synchronized

. So I need a counter variable. Normally I would use AtomicInteger

, but do I need this here?

PriorityBlockingQueue<TfIdfScore> allScores = sharedFeatureNameToScores.get(featureName);

synchronized (allScores) {

    AtomicInteger position = positionCounterMap.get(featureName);               
    position.getAndAdd(1);

    // Do other stuff..
}

      

Or could I use int

or Integer

? Does the block protect synchronized

all my actions inside the block?

In this example position

and allScores

depend on the same featureName

.

+3


source to share


3 answers


If you write all the code (and take the appropriate care), then you don't need to use both synchronized

and atomic. Just make sure that all operations on a given map and the counters it contains are synchronized on the same object while they are doing this ... and this piece of code should be thread safe.

On the other hand, if you are worried that someone will forget to sync, then atomic type probably won't solve the problem. The best solution is to make sure the map and counters are well encapsulated to reduce errors. (If you can reduce the amount of code, you can access state, which reduces the amount of space required to check thread safety.)




Does a synchronized block protect all my activities inside the block?

Not necessary.

You may still have thread safety issues if there is another code to access or update data structures and that code is out of sync in the right mutex; for instance the same instance allScores

.

+4


source


Synchronized - stricter than atomic or volatile. This way you don't need to use atomic synchronization

Synchronous

Synchronized methods allow a simple strategy for avoiding thread clutter and memory consistency errors: if an object is visible to more than one thread, all reads or writes to those object variables are done using synchronized methods.

Volatile



volatile field means that the variable will not be cached on core / threads processors. This way you will only have one copy of the variable for all cores / threads

atomic

The java.util.concurrent.atomic package defines classes that support atomic operations on single variables. All classes have get and set methods that act like reading and writing to volatile variables. That is, in the set there is-happens-before the relationship with any subsequent hit on the same variable. The atomic compareAndSet method also has memory consistency features like simple atomic arithmetic methods that are applied to integer atomic variables.

+1


source


In your code, you are using two different entities using featureName: sharedFeatureNameToScores

and positionCounterMap

.

To ensure that your code is thread safe, you need to ensure that changes to both of them are made using the same locking ( synchronized (allScores)

in your code). Once you meet this requirement, the user does not need an AtomicInteger, since the synchronized block protects both users, so access to it positionCounterMap

is done in exclusive mode.

+1


source







All Articles