Within a heavily synchronized subsystem, it is a good idea to break the subsystem into SynchronizedTightGroupsOfClasses
in order to contain synchronization. However, the system as a whole also needs to contain its synchronization.
split the system as a whole into separate subsystems where a small set of subsystems are synchronized, and the rest are not. Make the synchronized subsystems act like "traffic cops" to control the non-synchronized subsystems.
This technique will move most of the tricky multithreaded synchronization into small localized subsystems. Thus, the rest of the system can behave as if it was singlethreaded. As an added benefit, because it is easier to test singlethreaded applications, the system as a whole becomes easier to verify.
Moreover, because all the synchronization has been placed into separate modules, if it becomes necessary to optimize, correct or otherwise alter the behaviour of the multithreading in the system, it is remarkably simpler than if one had to chase locks and threads throughout the system.
it is sometimes better and more optimal, in an object-oriented system to create 3rd party objects that serve as monitors than to build synchronization into a subsystem [BTW, how is subsystem being used in the above?
]. For a very concurrent or parallel system, you may want to look into different idioms altogether such as CommunicatingSequentialProcesses
(CSP) or something like GenerativeCommunication
See also CoarseGrainLocking