Why is it good practice to have separate locks instead of object locks that are modified in a synchronized block in java?

While I am getting a few Java tutorials, I got the following statement.

It is good practice to have separate lock objects instead of having a clock on the object that is modified in a synchronized block. Explicit optimization of the code can have consequences.

What does he say exactly?

Say I have a code as shown below.

public class TestSynch(){ private Object lock1; private Object lock2; private List<Integer> list1; private List<Integer> list2; public void doListOne(){ synchronized(lock1){ // some server processing list1.add(/*some random number using random generator*/); } } public void doListTwo(){ synchronized(lock1){ // some server processing list2.add(/*some random number using random generator*/); } } } 

Let's say I have a method that calls the two above methods sequentially in a loop, and this method is called by two different threads.

What will imply with respect to optimizing Java code if I use list1 and list2 instead of lock1 and lock2?

-1
source share
2 answers

There may be reasons to have a separate object to block. For example, when the protected object can be null or when there are other ways to change it that do not need to be synchronized with each other or if the protected object is accessible (read-only) by code outside your api (you do not want this affected if someone decided to sync it).

But in general, if none of them apply or cause concern, there is nothing wrong with synchronizing with a mutable object. I have no idea what the "consequences" of the quoted excerpt indicate.

Please note that synchronization in general may not be the best approach to get started. Take a look at the * Lock classes provided by the java.util.concurrent package. You might want to use one of them, because they provide more flexibility - these are functions that you cannot perform with synchronization, for example, in terms of fairness or sharing.

0
source

What will imply with respect to optimizing Java code if I use list1 and list2 instead of lock1 and lock2?

It's not about optimization, it's about encapsulation.

In your example, there will be no practical difference between the synchronization of list objects and the synchronization on individual lock objects.

A common use case for a private lock object is when a class functions as a monitor. The classic monitor implementation looks like this:

 class MyMonitor { synchronized foo(...) { ... } synchronized bar(...) { ... } synchronized baz(...) { ... } } 

A private castle does the same thing as

 class MyMonitor { private Object lock = new Object(); foo(...) { synchronized(lock) { ... } } bar(...) { synchronized(lock) { ... } } baz(...) { synchronized(lock) { ... } } } 

The β€œproblem” with the classic way is that a client of the MyMonitor class could potentially use an instance of MyMonitor to synchronize something else:

 MyMonitor myMonitor = ...; synchronized( myMonitor ) { ... } 

Why has anyone ever written this? I have no idea. But if someone did this, then client-side use of the myMonitor object as a lock can prevent the MyMonitor class from using the same object as the lock.

The second way to use a private lock object is to ensure that even if the client actually uses MyMonitor to lock something else, it cannot interfere with the private locking of the MyMonitor instance.

None of this applies to your example, because in your example, lists are private variables that are (presumably) not visible to clients.

0
source

All Articles