The way you deal with that is, you have the object defend the consistency of the data that it controls. You have some kind of a mutex so that, when some thread is messing with certain data, no other thread can execute functions that mess with that data. They have to wait until the first thread is done, and then they can proceed to do their own operations on that data.
This has the advantage that it puts the data and the protection for the data in the same place. Something "way over there" can still call the function, but it will block until it's safe for it to modify the data.
(You don't put semaphores around all data. You think carefully about which data can be changed by multiple threads, and what consistency relationships that could violate, and you put them where you need to.)
Is that better or worse than Erlang's approach? Both, probably, depending on the details of what you're doing.