4

Is the synchronised keyword still required (ignore backwards compatibility, I'm thinking in terms of writing new code, today) or should we all be using the features available in the Concurrent and Collection packages?

Kevin D
  • 3,426
  • 27
  • 36

4 Answers4

5

Indeed it is needed (in specific situations). Just read through Java Concurrency in Practice, it is used there many times over.

Of course, since Java 5 we can usually happily solve problems using (almost) exclusively the java.util.concurrent toolbox. And even if we need to write our own thread-safe classes, synchronized can often be completely replaced by nonblocking algorithms such as CAS. However, CAS has its price as well, in that it requires very precise reasoning, tuning etc. and it is not well understood by lots of developers. Often it may provide no performance benefit, but it complicates the code. So there are cases when it is simpler and cleaner to just use a synchronized block.

Note also that locks are cheaper than they used to be as the JVM improves with every release. Long ago, this price was what turned off many developers from using them, but it is not so strongly justified anymore (and even if it is, only a concrete measurement can prove whether the performance bottleneck really is in locking).

Péter Török
  • 46,427
  • 16
  • 160
  • 185
1

The one place that synchronized is still used (at least in my code) is looping over Synchronized lists. The Javadocs for Collections.synchronizedCollection say that any time an iterator is used the entire block of code using the iterator needs to be synchronized. This is because you are not doing a single operation like add() or remove(), you are doing multiple operations.

Example code from Javadocs

Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
  Iterator i = c.iterator(); // Must be in the synchronized block
  while (i.hasNext())
     foo(i.next());
}

The only way I know to get around this limitation is to queue all operations in a SingleThreadExecutor, but that's a very expensive and archaic solution.

TheLQ
  • 13,478
  • 7
  • 55
  • 87
0

Well, it depends.

You can basically solve any problem using the concurrent and collection packages.
However, if you come to find, that you have a bottle neck just really in your synchronization, you'll probably need to do it by hand and the synchronised keyword might be just the friend you need.

I suppose, this is an unlikely problem to run into and usually, redesigning the thread responsibility will provide a cleaner solution than optimizing it by hand, while being sufficiently fast. I couldn't get my hands on the source of those packages, but I wouldn't be surprised if they actually used synchronised for implementation (but the opposite wouldn't surprise me either).

back2dos
  • 29,980
  • 3
  • 73
  • 114
0

Yes, the synchronized modifier is very much alive and required. Sure, you can use Locks and other stuff from the java.util.concurrent package but in many cases this is simply quite a big overhead. If you want to ensure that a certain piece of code gets executed exclusively the synchronized keyword is the quickest and safest solutation. There are a lot of situations, where obtaining a lock, getting it and releasing it simply isn't necessary.

So yes, for a good multithreaded program the use of the synchronized keyword is indeed required.

Christian Seifert
  • 2,096
  • 12
  • 19