2

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?

Community
  • 1
  • 1
scatmoi
  • 1,958
  • 4
  • 18
  • 32

3 Answers3

3

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.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
2

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

jdevelop
  • 12,176
  • 10
  • 56
  • 112
0

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.

Assen Kolov
  • 4,143
  • 2
  • 22
  • 32