2

we can synchronize the functions in a class, or we can lock its object in the thread, to create thread safety on a object.

    class DBresource {

        synchronized public void dosomething() throws InterruptedException {
            ...
            ...
        }
    }

OR

class MyThread extends Thread {

    public void run() {
        synchronized (r) {
            r.dosomething();
        }
}

Which is advisable and why?

Further, i could lock on the class DBResource too. How would that be different?

OR, use a dedicated Lock object. Is that discouraged or prefered and why?

Thanks.

jforex78
  • 315
  • 2
  • 11
  • @Makoto: I disagree, I think this is about where the locking code belongs, in the resource being protected or in the task accessing the resource. – Nathan Hughes Aug 14 '17 at 02:08

2 Answers2

3

If you use your second approach, putting the locking logic in the thread, then every time you need a different task to access that resource, you have to add locking code to the new task. And if any of the tasks that touch that resource don't perform locking or mess up how they do it, then the resource can become corrupted. This is going to result in a brittle application where adding a feature can cause breakage if the person adding the code doesn't get the locking exactly right. It's also the opposite of DRY.

With the first approach the object protects itself by implementing whatever locking is required to access it. Any threads accessing that object will have to acquire the lock specified by the class. There is no opportunity for any threads to bypass the locking on the resource.

Using a dedicated lock, for instance using a private final instance member, can make it harder for unrelated code from being able to acquire the lock on the object. Malicious code could still use reflection but it would prevent accidental access.

Using a class level lock prevents more than one thread from accessing the resource even if there are multiple resources. You could make a bottleneck this way.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Agreed. And accepted as answer. Thanks. Can you expand on the class level lock please? If a thread obtained lock on an object, only the threads waiting for lock on the same object will wait. Likewise, if a thread obtains a lock on the Class itself, only the threads wanting the lock on this Class will wait. No? If yes, how is a Class level lock worse than a object level lock? – jforex78 Aug 14 '17 at 05:09
  • @jforex78 Yes and yes, and it's worse because if you substitute a class-level lock for an instance-level lock you are locking all threads but one out of all the methods for all the instances, even if they're only going to play with one instance and no static variables. – user207421 Aug 14 '17 at 06:57
0

Making the method synchronized is simplest, and doesn't impose any requirements on the callers, other than that they avoid deadlocks in the usual way.

However it doesn't cover all cases. For example, if you're iterating over a collection, you should do that inside a block which synchronizes on the collection, to prevent it being modified during your iteration (unless you're using a concurrency-safe collection of course like the ones in java.util.concurrent). In general if you're calling multiple methods on an object in a way which requires consistent state across all the calls, you need to synchronize on it externally.

So the question as to which is better doesn't really have an answer. It depends on what you're doing.

user207421
  • 305,947
  • 44
  • 307
  • 483