Registered COM objects will belong to an apartment according to the ThreadingModel field (there's another article about COM apartments with a bigger, perhaps simpler table).
Basically, the ThreadingModel tells to which apartment the newly created object will belong to:
Not specified
Main STA (the first CoInitialize
d STA; if none exists, COM creates one, called the host STA)
Apartment
An STA (if we're in an STA, it'll be it, otherwise the host STA)
Free
An MTA (if we're in the MTA, it'll be it; otherwise, COM creates it, called the host MTA)
Both
Whatever is the current apartment
Neutral
The neutral apartment
If you might be using MTA objects and you doubt if they're "thread-safe" (this typically means it will use an instance level lock on each method/property call), then you can't really do much about it. For instance, you could have multiple STAs accessing the same MTA object concurrently.
Making calls from an STA doesn't necessarily give you this thread safety, unless you guarantee there are no other STAs and no one else is using the same objects.
The "guarantee" works the other way around: all calls made to an STA will be sequential. Even so, re-entrant calls are allowed while the STA makes an inter-apartment call, so this is not really a lock-like guarantee.
The call serialization is really coarse, because it's at the apartment level, so all calls to the same STA, no matter the object, will be executed one at a time (but possibly one over the other in a re-entrant way).
EDIT: Call re-entrancy can be controlled with an IMessageFilter.