I have the below class
public class Example{
public static List<String> list = new ArrayList<String>();
public static void addElement(String val){
synchronized(list){
list.add(val);
}
}
public static synchronized void printElement(){
Iterator<String> it = list.iterator();
while(it.hasNext()){
//print element
}
}
}
Will the iterator() call in the printElement method throw ConcurrentModificationException? The basic question is if the lock on class object is acquired(as done in printElement method), will it lock the class members/ variables too? please help me with the answer.
Object Level Locks − It can be used when you want non-static method or non-static block of the code should be accessed by only one thread. Class Level locks − It can be used when we want to prevent multiple threads to enter the synchronized block in any of all available instances on runtime.
Class level lock prevents multiple threads to enter a synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 10 instances of a class, only one thread will be able to access only one method or block of any one instance at a time.
Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor.
Major difference between lock and synchronized: with locks, you can release and acquire the locks in any order. with synchronized, you can release the locks only in the order it was acquired.
Does a lock on class, locks class variables too? - java
Your lock is on your instance, not your class. And no, it only locks the instance.
Will the iterator() call in the printElement method throw ConcurrentModificationException?
It will if the code in that method modifies the list during the iteration. But if all of your code in that class also synchronizes, and you haven't given a reference to that list to anything outside your class, then you know that only the code in that method is running.
You'd probably be better off, though, synchronizing on the list itself. That way, even if you've given out a reference to the list, assuming all code that uses it synchronizes on it, you'll be safe from concurrent mods:
public static void printElement(){
// ^--- No `synchronized ` here unless you REALLY need it for other reasons
synchronized (list) {
Iterator<String> it = list.iterator();
while(it.hasNext()){
//print element
}
}
}
If you are giving out references and want to be really sure, either use a list returned by Collections.synchronizedList
or something from the java.util.concurrent
package.
No, a synchronized method does not lock the object variables, a synchronized method will lock only this
.
Your code is not thread safe, since you are locking on different objects on addElement and printElement. There is nothing preventing the insertion to occur while iterating the list, if both method are called concurrently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With