This is part of ExpertCodingSkills.
Multi-threading is a fact of life for programmers. Modern processors and operating systems are capable of performing multiple tasks virtually at once. Today's graphical user interfaces require long-running computations, slow input/output operations, and web services calls to be performed via background threads.
However, writing and calling multi-threaded libraries is often difficult. Deadlocks and intermittent buggy behavior are commonplace in multi-threaded applications. Multi-threaded software can also scale poorly due to excessive resource locking. Software objects that allow callers to make simultaneous requests via multiple threads introduce the same multi-threading issues discussed above.
The best way to avoid threading issues is to forbid multi-threaded access. Therefore, when writing software components, provide interfaces that only require a single-threaded usage model. In other words, it's illegal for two or more threads to call methods on an object at the same time.
Some objects use "heavyweight" resources such as a large thread pool, disk buffers, etc.. These types of objects tend to require multi-threaded programming models, either because multi-thread communication is desirable or creating multiple objects isn't practical. However, instead of allowing callers to interact with these objects directly via multiple simultaneous threads, create "flyweight" objects that stand between the caller and the object that manages the heavyweight resources. The caller is still responsible for creating one "flyweight" object per thread.
Ensuring that an object can only be called by one thread at a time has numerous benefits. First, the interface can have state since multiple threads can't interfere with each other. See KeepItSimple. Secondly, the object can decide which resources are shared across threads and which are local to their client. The fewer resources that are shared, the better the software can scale up. Most importantly, thread-less interfaces are generally easier to design, implement, and use.
