Three fast problems about Java synchronization block

As far as I know, the following code, in the synchronized block, is an instance of a counter

Question 1: in the following example, does this mean that when thread a reaches the synchronization block, thread B is prevented from doing anything to the instance of the counter? In other words, does this mean that threads can continue to execute as they want, but when the synchronization block is reached, the other stops doing anything on the class until the block exits?

public class Counter {

    public void increment() {
        // Some code

        synchronized (this) {  // <---- "this" is an instance of Counter
             // Some more code
        }
    }
}

Compare the above code

public class Counter {

    List<String> listOfStrings = new ArrayList<String>();

    public void increment() {
        // Some code

        synchronized (listOfStrings) {  
             // Some code that deals with 
             //    listOfStrings 
        }
    }
}

Problem 2: in the above example, once thread a reaches the synchronization block, thread B can continue to read and write anything in the class, except listofstrings ArrayList, which is a mutex in the synchronization block Is it correct?

Question 3: if we need to modify multiple objects, this is the mutex we should use. Is this more correct?

For example:

public class Counter {

    List<String> listOfStrings = new ArrayList<String>();
    List<Integers> listOfIntegers = new ArrayList<Integers>();

    public void increment() {
        // Some code

        synchronized (this) {  
             // Some code that deals with 
             //    listOfStrings and listOfIntegers
        }
    }
}

Do I understand correctly? If I am wrong, please correct it

Solution

No, thread B is prevented from entering the synchronized code block. It can still input other methods: those that are not synchronized and those that use different object synchronization Thread B can not only access blocks synchronized with objects occupied by different threads (synchronization locks are reentrant)

This is not the case. The fact that listofstrings is used as a mutex in a synchronization block does not mean that other threads cannot explicitly access the object It only means that other threads cannot access the synchronization block protected by the same object Therefore, if you want to protect access to the listofstrings object, you must synchronize all methods accessing the object and use the same lock (for example, listofstrings)

BTW every object you synchronize should be final to avoid headaches

Yes, No Consider the following:

List<String> listOfStrings = new ArrayList<String>();
List<Integers> listOfIntegers = new ArrayList<Integers>();
Set<String> setOfStrings = new HashSet<String>();
Set<Integers> setOfIntegers = new HashSet<Integers>();

If one method only accesses lists and the second method only accesses collections, you can safely use two locks - one for the first method and the second for the second method Synchronization is not harmful, but it affects performance:

private final Object listLock = new Object();
private final Object setLock = new Object();

then:

synchronized (listLock) {  
     // Some code that deals with 
     // setOfStrings and setOfIntegers
}

//...

synchronized (setLock) {  
     // Some code that deals with 
     // setOfStrings and setOfIntegers
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>