List of principles for multithreaded programming in Java
When writing multithreaded programs, you should adhere to certain rules that help ensure decent application performance, combined with convenient debugging and ease of further code maintenance.
- Always give meaningful names to your streams. The process of debugging, finding errors, or tracing an exception in multi-threaded code can be challenging. OrderProcessor, QuoteProcessor, or TradeProcessor are much more informative than Thread1, Thread2 and Thread3. The name should reflect the task being performed by this thread.
- Avoid blocking or try to reduce sync scales. Blocking is expensive, and context switching is even more resource intensive. Try to avoid synchronization and blocking as much as possible, and organize the critical section to the minimum necessary. Therefore, the synchronized block is always preferable to the synchronized method, additionally giving the possibility of absolute control over the lock scale.
- Handle flow interruptions with extreme care. There is nothing worse than a resource remaining locked or a system in an inconsistent state due to an unconfirmed transaction.
- Remember to handle exceptions. InterruptedExceptions thrown should be handled adequately, not just suppressed. Also, do not neglect Thread.UncaughtExceptionHandler. When using a thread pool, remember that it often just "swallows" exceptions. So, if you sent Runnable to execute, you must definitely put the task execution code inside the try-catch block. If a Callable is placed on the pool queue, you need to make sure that the execution result is always fetched using a blocking get() so that if it occurs, it is possible to rethrow the resulting exception.
- Synchronizers should be chosen between synchronizers and wait() and notify(). First, synchronizers like CountDownLatch, Semaphore, CyclicBarrier, or Exchanger make your code easier to write. It is very difficult to implement complex control flow using wait() and notify(). Secondly, these classes are written and supported by true masters of their craft, and there is a chance that in future versions of the JDK they will be optimized from the inside or replaced with a more efficient external implementation.
- Almost always, using Concurrent collection is more advantageous than using Synchronized collection, because the former are more modern (using all the language innovations available at the time of writing) and scalable than their synchronized counterparts.
Read also:
Comments
Post a Comment