Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should I use as a lock object of a synchronized statement in Java

Could anyone explain what is the difference between these examples?

Example # 1.

public class Main {

    private Object lock = new Object();
    private MyClass myClass = new MyClass();

    public void testMethod() {
        // TODO Auto-generated method stub
        synchronized (myClass) {
            // TODO: modify myClass variable
        }
    }

}

Example # 2.

package com.test;

public class Main {

    private MyClass myClass = new MyClass();
    private Object lock = new Object();

    public void testMethod() {
        // TODO Auto-generated method stub

        synchronized (lock) {
            // TODO: modify myClass variable
        }
    }

}

What should I use as a monitor lock if I need to take care about synchronization when modifying the variable?

like image 827
Maksim Dmitriev Avatar asked Dec 27 '22 09:12

Maksim Dmitriev


2 Answers

Assuming that Main is not intended to be a "leaky abstraction", here is minimal difference between the first and second examples.

It may be better to use an Object rather than some other class because an Object instance has no fields and is therefore smaller. And the Object-as-lock idiom makes it clear that the lock variable is intended to only ever used as a lock.

Having said that, there is a definite advantage in locking on an object that nothing else will ever see. The problem with a Main method synchronizing on a Main (e.g. this) is that other unrelated code could also be synchronizing on it for an unrelated purpose. By synchronizing on dedicated (private) lock object you avoid that possibility.


In response to the comment:

There is a MAJOR difference in the two cases. In the first you're locking the object that you want to manipulate. In the second you're locking some other object that has no obvious relationship to the object being manipulated. And the second case takes more space, since you must allocate the (otherwise unused) Object, rather than using the already-existing instance you're protecting.

I think you are making an INCORRECT assumption - that MyClass is the data structure that needs protecting. In fact, the Question doesn't say that. Indeed the way that the example is written implies that the lock is intended to protect the entire Main class ... not just a part of its state. And in that context, there IS an obvious connection ...

The only case where it would be better to lock the MyClass would be if the Main was a leaky abstraction that allowed other code to get hold of its myClass reference. That would be bad design, especially in a multi-threaded app.

Based on the revision history, I'm pretty sure that is not the OP's intention.

like image 110
Stephen C Avatar answered Jan 05 '23 00:01

Stephen C


The statement synchronization is useful when changing variables of an object.

You are changing variables of myClass so you want to lock on myClass object. If you were to change something in lock then you want to lock on lock object.

In example #2 you are modifying myClass but locking on lock object which is nonsense.

like image 22
drzymala Avatar answered Jan 05 '23 01:01

drzymala