scatmoi
scatmoi

Reputation: 2028

How to reconcile synchronization on a private object by multiple classes

It is well known that synchronization is recommended on a final private object (vs. synchronizing on this or even a protected data member).

But what happens when I have multiple classes (modules) in my application that need to synchronize on a common object?

Is there a way to reconcile these two seemingly contradicting requirements?

To better explain, if I have a private data member of class Owner defined as:

private final Object $01pfo = new Object[0]; 

Then any method in Owner could simply use it:

  protected void anyMethod()  {
    synchronized ($01pfo) {
          // do your thing
    }
  }

But if I want to synchronize on $01pfo from a different class (say User), is my only option to make $01pfo protected or public?

protected final Object $01pfo = new Object[0]; 

Is there a better approach? or solution?

Upvotes: 2

Views: 157

Answers (3)

jdevelop
jdevelop

Reputation: 12296

synchronized blocks are working well in case if they are not spread among several objects.

in case if you need to synchronize operations using single lock in several classes - it's better to take a look at Lock implementations.

It will give you much more freedom in granularing access to resources in several threads

Upvotes: 2

Assen Kolov
Assen Kolov

Reputation: 4403

The link you provide is clear about the situations where to consider private final instead of this:

  • we are talking about instance synchronization;
  • if you need granularity in your locking other than synchronized(this) provides, then synchronized(this) is not applicable so that's not the issue.

When you need another granularity, feel free to use another synchronization object. BTW, in your example,

 private final Object $01pfo = new Object() 

would be enough.

Upvotes: 0

Vikdor
Vikdor

Reputation: 24124

I consider using the package-privateness of protected keyword as a hack. In your use case, it appears that the classes are collaborating to perform a particular task in a synchronized manner. I would define a Lock object in the class/method that initiates this task and make the Lock object available to all the classes involved, explicitly, by passing as a constructor argument.

Upvotes: 3

Related Questions