Concurrency- Chapter1- Atomic & Collections
As we know, there is a race condition in threads and we use the synchronized keyword to solve it. This is a somewhat expensive way, but it is not desired to be used much. That’s why atomic classes are used.
The classes such as AtomicInteger do not use a lock; rather, they
internally use volatile variables and a low-level mechanism known as
Compare-And-Set (CAS). For this reason, using AtomicInteger and
related classes is faster than using locks using synchronized
Let’s look at an example of how we can use the Atomic.
If we want to compare both of them;
- We added for loops to increment/decrement the integer value.
- When we run the application, we will see that IntegerValue is changeable because of the race condition. But AtomicInteger value is a constant and true result.
Integer value = 2 AtomicInteger value = 0
- The java.util.concurrent package provides a number of classes that are thread-safe equivalents of the ones provided in the collections framework classes in the java.util package.
- For example, java.util.concurrent.ConcurrentHashMap is a concurrent equivalent to java.util.HashMap.
- The main difference between these two containers is that you need to explicitly synchronize insertions and deletions with HashMap,
whereas such synchronization is built into the ConcurrentHashMap.
- It is better to use a concurrent collection class anytime that we are going to have multiple threads modify a collection object outside a synchronized block or method, even if you don’t expect a concurrency problem.
There is a bad approach to working with collections,
Because it is better approach using ConcurrentHashMap rather than synchronized.
ConcurrentHashMap provides higher performance under high read-write operations compared to similar data structures.
Let’s look at another example;
If we want to add a new item while reading the Array or something.
- When we run this application, we will get an error.
- ArrayList is fail-fast. That’s why we get an error java.util.ConcurrentModificationException
- we can use -> new CopyOnWriteArrayList<>(); rather than ArrayList.
CopyOnWriteArrayList is commonly used in multi-threaded environment situations where reads far more than writes.
[one, two, three, four, four, four]
When Can we use these methods?
- If we know at the time of creation that your object requires synchronization, then you should use one of the concurrent collection classes listed.
- On the other hand, if we are given an existing collection that is not a concurrent class and needs to access it among multiple threads, you can wrap it using the methods. (SynchronizedCollection,List,Map..)
- While the methods in (SynchronizedCollection,List,Map..)
- They do not synchronize access on any iterators that you synchronize may create from the synchronized collection. Therefore, it is imperative that we use a synchronization block. If we need to iterate over any of the returned collections is synchronized collection methods.
What is the difference between Collections.synchronizedList and Concurrent Collection?
When we use the synchronized keyword like the below,
- One thread works in the method. So, just method is blocked.
- But when we use Collections.synchronizedList, all collections will be locked.
For Concurrent Collection
More than 1 thread may work on the same collection.
Lock mechanism is not on all collection.
The logic here is that more than one thread cannot run/work on the same element/index.