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
.
source to share
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
.
source to share
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.
source to share
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.
source to share