Pranav Arora
Pranav Arora

Reputation: 1013

Synchronizing on a object and changing one of its field

I am trying to understand a part of code which involves synchronizing on an object and one of the synchronized blocks changes some fields of the object. The code I am looking at is similar to the following:

public class ClassA {
    private ClassB someObject = new ClassB();

    public void FuncA() {
        synchronized(someObject) {
            //change some field of someObject
        }
    }

    public void FuncB() {
        synchronized(someObject) {
            //change some field of someObject
        }
    }
}

Is this a safe practice to do? I have read a few pages online describing the safe practices for the locks but none seem to deal with a similar example.

Any help is appreciated. Thanks!

Upvotes: 0

Views: 393

Answers (3)

davidxxx
davidxxx

Reputation: 131316

You have multiple ways to synchronize the access to a method.
One appears better than another according to the synchronization requirement.

Is this a safe practice to do?

It is a safe practice if it is used for a use case that suits.
Here the synchronization makes sense as it locks on someObject which the two methods perform modifications on them.
Yes you could synchronize on this or synchronize the whole methods such as :

public class ClassA {
    private ClassB someObject = new ClassB();

    public void FuncA() {
        synchronized(this) {
            //change some field of someObject
        }
    }

    public void FuncB() {
        synchronized(this) {
            //change some field of someObject
        }
    }
}

but these would lock the whole object while this may not be required.

Upvotes: 1

Richard
Richard

Reputation: 9928

Yes this is safe. someObject is private so only FuncA and FuncB have access to it. They both synchronize on someObject so only 1 of the methods at a time will execute on someObject even if from different running threads.

Note that it is important that all methods of ClassA that want to access someObject should do so within synchronized on someObject to avoid any risk of reading or writing inconsistent state into someObject (unless you understand exactly what you are doing!).

Upvotes: 1

Andy Turner
Andy Turner

Reputation: 140309

Yes, that's fine.

For example, this is basically what you (can) do when writing to an ArrayList from multiple threads: you synchronized on the list, and update its fields (the internal array, size etc).

The caveat is that you mustn't also access the someObject in a non-synchronized way anywhere.

public class ClassA {
    private ClassB someObject = new ClassB();

    public void FuncA() {
        synchronized(someObject) {
            //change some field of someObject
        }
    }

    // ...

    // BAD! Don't do this.
    public void FuncC() {
        // read some field of someObject
    }
}

Upvotes: 1

Related Questions