In this chapter, we will cover the following topics:
- Using immutable objects when possible
- Avoiding deadlocks by ordering locks
- Using atomic variables instead of synchronization
- Holding locks for as short time as possible
- Delegating the management of threads to executors
- Using concurrent data structures instead of programming yourselves
- Taking precautions using lazy initialization
- Using the fork/join framework instead of executors
- Avoiding the use of blocking operations inside a lock
- Avoiding the use of deprecated methods
- Using executors instead of thread groups
- Using streams to process big data sets
- Other tips and tricks