The problem is, I suppose, that the matter is much to complicated for the average programmer. Therefore I tried to compile ten simple advises for concurrency in Java:
- if 2 or more threads access the same data, synchronization is necessary. Period.
- synchronized methods are not expensive (at least not as expensive as the time needed to debug the data inconsistencies you get otherwise)
- iterating over a synchronized collection is not safe (i.e. is not protected against ConcurrentModificationExceptions)
- many classes in the Standard Java library, which you think of as thread-safe, are not. (e.g. DateFormat)
- don't try to invent your own clever solutions to avoid synchronization (they are broken most of the time)
- use the classes from java.util.concurrent, but read the javadoc carefully!
- check-and-act operations (e.g. incrementing a counter) are not atomic and thus inherently not thread-safe
- learn the basics:
- Thread.start/join
- synchronized-blocks
- Object.wait/notify/notifyAll
- volatile
- programming in a concurrent scenario is not intuitive!
- When multiple locks are involved in a single operation, be aware of lock ordering or deadlocks will occur sooner or later.
1.) with synchronization in this context I mean all kind of inter-thread-communication. Java synchronized-blocks are just the easiest to use. For example, in rare cases volatile may be enough to synchronize.
2.) Synchronization is expensive compared to non-synchronized methods. But it is far cheaper as it used to be in early Java VMs. VM vendors are working very hard to make it even cheaper in future VMs resp. to remove synchronization alltogether on-the-fly if the VM can prove that it is (currently) not needed.
3.) I'm speaking about the usual Collections.synchronizedXyz and Vector/Hashtable. There are, of course, some collection classes which are declared to be thread-safe (see java.util.concurrent), but they usually sacrifice some other guarantees (e.g. iterator may skip some elements)
5.) And be carefully when you use non-standard concurrency mechanisms invented by others (see e.g. DCL)
7.) atomic compare-and-set operations are a nice way to implement thread-safe check-and-set operations, but they are non-trivial to use
10.) Try to avoid inner-outer-lock constructs where sometimes first the outer than then inner lock is acquired and sometimes vice versa. If you must lock two similar objects try to order them based on id (popular example: order locks on bank accounts based on the account number)
PS: I do obviously not agree with this guy :)
No comments:
Post a Comment