Sharing Time (Illusion of concurrency).
Any number of threads(running programs) can be coordinated using Thread Scheduler. It is responsible for communicating with each thread and allowing it to proceed with one step, or for specified quantum of time, or until interrupted, for example by passing a token to it. When the thread is done with it's job, it passes token back. Then scheduler proceeds with next thread in queue (or ring).
True concurrency may be achieved with multiple processors.
But once we have concurrency mechanism, how we coordinate threads?
Tokens (preconditions) might be accumulated by entry mechanism, then when all preconditions are met, thread might be allowed to run. (To appear in Thread Scheduler's queue). Multiple tokens might be joined by boolean operators, to allow for conditionality. (for example: precondition A is met when precondition B is met or when precondition C is met).
Communication must be arranged to avoid (or overcome) problems of concurrency, such as Mutual Exclusion, Dining Philosophers, Readers and Writers, Producers and Consumers.
Events are useful in this model of synchronization.