Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a lock on class, locks class variables too? - java

Tags:

java

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.

like image 647
user2813978 Avatar asked Sep 25 '13 07:09

user2813978


People also ask

What's the difference between class lock and object lock Java?

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.

What is class lock in Java?

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.

How do Java locks work?

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.

What is difference between lock and synchronized in Java?

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.


2 Answers

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.

like image 196
T.J. Crowder Avatar answered Sep 25 '22 00:09

T.J. Crowder


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.

like image 20
fbafelipe Avatar answered Sep 26 '22 00:09

fbafelipe