1

I have a base class that contains some lists, queues, and other fields which determine its state. In the base class I only access these fields within a protected lock object since there could be multiple threads using it. I provide methods for inheritors of this base class and these methods use the lock object to ensure the state remains valid. (In other words, the classes that inherit from the base access the methods rather than the individual fields themselves so they don't need to know/remember to use the lock object). So my inclination is to make the lock object and fields private so I never need to worry about inheritors using them wrong. The downside to that approach is that anytime inheriting classes need new functionality with these fields I need to modify the base class to create a new method.

Is there a best practice I'm missing? If not, which is the better option, private lock and fields or protected?

  • 4
    Show us a code example of the base class, the derived class, the lock object definition, and the base class's accessors, so that we're clear about what you're describing. – Robert Harvey Feb 28 '15 at 00:41
  • Can a subclass abuse the locking mechanism and violate threading guarantees posited by the base class? –  Feb 28 '15 at 01:00

1 Answers1

2

It depends, is the state you're locking private or protected?

If it's protected, I recommend you reconsider.

Once you've reconsidered, make the lock object as public as the most public shared state. If you trust derived types to use the state properly, then you should trust them to handle the locking properly. If you don't provide the lock, they'll be tempted to have another locking mechanism leading to possible deadlock, concurrency bugs, and thermonuclear war.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • 1
    Agreed. In fact, if you're handing out a reference to the shared state, but not providing access to the lock object, you are forcing callers to either use their own lock object (creating conflicts with the private locking code in your class), or you are forcing them to forego any attempt at synchronization. So you need to expose the lock object and trust your callers. If, on the other hand, you just provide public methods to *act* on the shared state without exposing a mutable reference to that state, keep the locking private. – Craig Tullis Feb 28 '15 at 05:56