Workflow execution follows single-threaded apartment conventions - that is, one particular instance of a workflow can only be executed by one thread at a time within any runtime. This is by design.
The workflow runtime uses an internal scheduling queue to execute operations for workflow instances, so two threads invoking operations on the same workflow instance will be serialized to the scheduler queue first, then invoked in sequence either by a new thread scheduled by the runtime (default scheduling) or by the thread donated by the calling context for each operation (manual scheduling).
When using the persistence service, the workflow runtime also ensures that the database version is synchronized as well - another workflow runtime running on another process / machine cannot load the same workflow instance from persistence if it is currently open by another workflow runtime.
This means that you don't have to be concerned with thread-safety on code executing within a workflow model (eg you don't have to lock property setters), and you don't have to be concerned with race conditions.