- concurrency related code should be kept separate from other code.
- limit the scope of data as much as possible to avoid race conditions - e.g.
only access shared data in one point of the code (no duplication!) so you can't
accidentally forget to protect/lock the data elsewhere.
- Change object design of shared data so that you don't force
objects using the data to manage sharing as well
- Use copies instead of sharing when possible (e.g. local copy to a thread
to be merged later in the main thread)
- threads should be as independent as possible - share as little with
other threads as possible
- most concurrent problems are variations of the reader-writer, producer-consumer,
and dining philosophers problems
- keep critical sections as small as possible