0

In Java an Object itself can act as a lock for guarding its own state . This convention is used in many built in classes like Vector and other synchronized collections where every method is synchronized and thus guarded by the intrinsic lock of the object itself . Is this good or bad ? Please give reasons also .

Inquisitive
  • 7,476
  • 14
  • 50
  • 61
  • Read [Differences between Vector and ArrayList](http://javapapers.com/core-java/java-collection/difference-between-vector-and-arraylist-in-java/) – Luiggi Mendoza Jun 28 '12 at 14:26
  • 1
    It's meh. No big difference. – Louis Wasserman Jun 28 '12 at 14:32
  • 1
    possible duplicate of [Avoid synchronized(this) in Java?](http://stackoverflow.com/questions/442564/avoid-synchronizedthis-in-java) – assylias Jun 28 '12 at 14:46
  • 1
    @assylias good job finding the duplicate although the wordings of the questions were quite different. I realised only after you provided that link.Thanks. – Inquisitive Jun 29 '12 at 09:44

2 Answers2

3

Pros

  • It's simple.
  • You can control the lock externally.

Cons

  • It breaks encapuslation.
  • You can't change its locking behaviour without changing its implied contract.

For the most part, it doesn't matter unless you are developing an API which will be widely used. So while using synchronised(this) is not ideal, it is simple.

seh
  • 14,999
  • 2
  • 48
  • 58
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • *So while using synchronised(this) is not idea* - not a good idea I suppose? baring that - the answer pretty much covers all except due to monitor expose it's possible malicious code to pose security/DoS threat like `synchronized(Thread.class){for(;;){/*sleepsome*/}};` – bestsss Jun 28 '12 at 14:39
  • @Peter ,"how does it break encapsulation " and why do you say that "you can't change its locking behaviour without changing its implied contract." ? Can you please elaborate in the answer itself? – Inquisitive Jun 28 '12 at 14:41
  • Encapsulation requires that behaviour is hidden from the caller of an object, but the lock for an object is exposed. Code locking an object by synchronized() externally can break if you use a `Lock` instead. – Peter Lawrey Jun 28 '12 at 14:55
  • Can you give an example how encapsulation is broken here? @PeterLawrey – aamir Jan 24 '17 at 19:27
  • 1
    @aamir when you have a reference to an object you also have a reference to the intrinsic lock of that object. There is no way for an object to hide other than to ignore it and use another one. ideally, locks should be hidden from the caller of any object and it should control it's own lock (and in most cases not even have one) – Peter Lawrey Jan 25 '17 at 10:30
  • @PeterLawrey regarding change of locking behavior without changing its implied contract, I wanted to clarify if my understanding is correct. Is it because someone else also might hold the intrinsic lock externally changing it would break such code? – aamir Jan 25 '17 at 16:31
  • @aamir yes, you can run into obscure problems with `Thread` for example. – Peter Lawrey Jan 25 '17 at 17:23
1

Well Vector, Hashtable, etc. were synchronized like this internally and we all know what happened to them...

I honestly can't find any good reason to do synchronization like this. Here are the disadvantages that I see:

  1. There's almost always a more efficient way of ensuring thread-safety than just putting a lock on the entire method.
  2. It slows down the code in single threaded environments because you pay the overhead of locking and unlocking without actually needing the lock.
  3. It gives a false sense of security because although each operation is synchronized, sequences of operations are not and you can still accidentally create data races. Imagine a collection which is synchronized on each method and the following code:
if(collection.isEmpty()) {
    collection.add(...);
}

Assuming the aim is to have only a single item added, the above code is not thread safe because a thread can be interrupted between the if check and the actual call to add, even though both operations are synchronized individually, so it is possible to actually get two items in the collection.

Inquisitive
  • 7,476
  • 14
  • 50
  • 61
Tudor
  • 61,523
  • 12
  • 102
  • 142
  • synchronizedSet/List/Map etc. are still widely used. Properties (that extends Hashtable) is still widely used. Point 2 - *slows down*, due to the exceptionally broadly used idiom of synchronize this/synchronized that - the JVMs play smart and optimize away the code they deem single threaded. HTM can optimize away synchronized too (for readers). Point 3 requires special care/explanation and it's true for any possible race, the check has to be after the operation and the operation should be rolledback if the conditions are not met (any more). – bestsss Jun 28 '12 at 15:45