Synchronized keyword - does it block two objects?

Let's say I have two hash maps hashMap1 and hashMap2 and a multithreaded parallel Java program. If I put a synchronized block

synchronized(hashMap1) {
hashMap1.put(5, "Hello");
hashMap2.put(10, "Hi");
}

      

Since only one thread can access hashMap1 at a time, can only one thread be able to access hashMap2? I am essentially asking if hashMap2 will be protected from multiple threads accessing it at once, just like hashMap1.

Thank!

+3


source to share


3 answers


No, it synchronized

does not "block objects". What your block of code is doing, it takes a thread to block hashMap1 before it can enter the block. hashMap1 itself is not "locked" except that its monitor is being purchased. (It might be clearer to call this a monitor than a lock.) A monitor is something that all objects have, by itself it does nothing to control access to the object to which it belongs. If hashMap2 is available elsewhere, this synchronized block does nothing to prevent this from happening.

The purpose of a synchronized block is to require a thread to acquire a monitor. All places where you want this resource to be protected from concurrent access requires that the same lock be required. These are blocks of code, protected with using synchronized

, that indicate when to use the lock object that controls access.

The monitor selection can be kept separate from the real objects, protected from concurrent access. You can have a dedicated lock object and use it without requiring you to use the lock on what you are protecting. (The only benefit is it can help in organization, if there is only one thing you are referring to, it may be convenient to monitor that thing.) Using a dedicated lock might be clearer:



public class Foo {
    private final Object LOCK = new Object();

    private Map hashMap1 = new HashMap();
    private Map hashMap2 = new HashMap();

    public void doStuff() {
        synchronized(LOCK) {
            ... // do stuff with hashMap1 and hashMap2
        }
    }
}

      

Keeping access to a lock private to an object means that the object can restrict who can acquire the lock (as opposed to synchronized(this)

). Also, don't use things like "Strings" or "Booleans" that can be interned, cached, or otherwise accessible from other parts of the program.

+4


source


The answer depends on the design of your application. After all, synchronization is a concept of choice - any thread can choose to ignore locks and just access shared objects independently.

Similar to your example, if you are sure that the only access to hashMap2

is in the synchronized block shown in your example, then you are effectively locking it while locking on a different object.



It may be clearer if future maintainers must take locks on both objects before proceeding with them.

0


source


The keyword synchronized

forces a thread to acquire a lock when entering a method, only one thread can execute this method at a time (for a given object instance, if it is not a static method).

In your situation, if inside the method synchronized

is the only place where hashmap2 is changed, then yes, it will be protected from multiple threads at once. However, if hashmap2 is modified somewhere else in addition to the method synchronized

, there is no guarantee that hashmap2 will be protected.

0


source







All Articles