Many people prefer using a monitor as an alternative to a semaphore.
A Monitor is essentially a class with private methods, plus a queue. Processes that want to enter a monitor (i.e., run *any* of the private methods) must wait in the queue. Only when there are no processes in the monitor (i.e., no one is running any of the private methods) is a process allowed into the queue. The monitor itself runs the single threaded portions. This guarantees that there can only be one process executing inside a monitor at any one time.
Monitors are well structured when compared to semaphores and thus are easy to understand and implement.
A common bug with semaphores is a process that acquires a semaphore, does what it needs to do, but accidentally fails to release the semaphore. That process may have finished long before the programmer notices that other processes are deadlocked, waiting forever for someone to release the semaphore.
Monitors make this common problem impossible. It is still possible for a system using monitors to deadlock, but only when the process is stuck in an infinite loop inside the monitor, which is much easier to debug than a process that seemed to finish successfully a long time ago.