Problems start when you have to share objects between concurrent tasks.
Solutions are based on atomic operations. An atomic operation is an operation which can't be interrupted by another one.
In a bare-metal environment:
In an RTOS environment, high-level facilities:
Mutexes and semaphores must be used with caution, otherwise: priority inversion, deadlock.
Queues can be an easier solution. They can be used to synchronize tasks, and to exchange data between tasks.
In some contexts, mutexes and semaphores can be better than queues. You have to remember that they exist.
In the end, many things depend on the architecture, i.e. on the developer(s).