views:

96

answers:

3

In many MSDN documents, this is written under the Thread Safety heading;

"Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."

for example; here

can someone explain it please in a rather simple way? Thank you :)

+3  A: 

You may access any public static member of that class from multiple threads at the same time, and not disrupt the state of the class. If multiple threads attempt to access the object using instance methods (those methods not marked "static") at the same time, the object may become corrupted.

A class is "thread-safe" if attempts to access the same instance of the class from multiple threads at the same time does not cause problems.

Michael Petrotta
+3  A: 

An object being "thread safe" means that if two threads are using it at (or very near, on single-CPU systems) the exact same time, there's no chance of it being corrupted by said access. That's usually achieved by acquiring and releasing locks, which can cause bottlenecks, so "thread safe" can also mean "slow" if it's done when it doesn't need to be.

Public static members are pretty much expected to be shared between threads (Note, VB even calls it "Shared"), so public statics are generally made in such a way that they can be used safely.

Instance members aren't usually thread-safe, because in the general case it'd slow things down. If you have an object you want to share between threads, therefore, you'll need to do your own synchronization/locking.

cHao
+2  A: 

Eric Lippert has an excellent blog post about this. Basically it's somewhat meaningless on its own.

Personally I don't trust MSDN too much on this front, when I see that boiler-plate. It doesn't always mean what it says. For example, it says the same thing about Encoding - despite the fact that we all use encodings from multiple threads all over the place.

Unless I have any reason to believe otherwise (which I do with Encoding) I assume that I can call any static member from any thread with no corruption of global state. If I want to use instance members of the same object from different threads, I assume that's okay if I ensure - via locking - that only one thread will use the object at a time. (That's not always the case, of course. Some objects have thread affinity and actively dislike being used from multiple threads, even with locking in place. UI controls are the obvious example.)

Of course, it becomes tricky if objects are being shared unobviously - if I have two objects which each share a reference to a third, then I may end up using the first two objects independently from different threads, with all the proper locking - but still end up corrupting the third object.

If a type does advertise itself to be thread safe, I'd hope that it would give some details about it. It's easy if it's immutable - you can just use instances however you like without worrying about them. It's partially or wholly "thread-safe" types which are mutable where the details matter greatly.

Jon Skeet
What MS's little note means is, "We didn't do much/any locking in the instance methods [probably for performance reasons]. So if you go and sic a dozen threads on it, and it messes up, don't come crying to us. It's not a bug. And we warned you."
cHao
@cHao: There's *much* more to getting multi-threading right than just sticking a lock on instance methods. You often want to make a whole *series* of method calls work atomically - no amount of internal locking will help in that case. Iterating through a collection is the obvious example.
Jon Skeet
@Jon: Agreed, there's a lot more to it. But there's not much more at all that could be expected of MS, as built-in atomicity across multiple method calls doesn't even make sense from anyone who values stability. (It'd require API docs that say stuff like "If you call IsEmpty(), and it returns false, you MUST call Remove() or ReleaseLock() to avoid deadlocks".) And even in a single method, it can cause performance issues if it's used unnecessarily. So MS rightly didn't bother. That's my point.
cHao
@cHao: I agree that MS rightly didn't attempt it - I'm taking issue with the idea that it's to do with "bothering". Your first comment implies that locking in instance methods would usually be enough, and I'm disputing that. That's all.
Jon Skeet
@Jon: locking isn't everything, not even close. But without it, or hardware-level atomic instructions like compare-and-swap (which is pretty much the same thing as a very-short-term lock), multithreading can't be done right. So when i think "thread safe", locking immediately springs to mind. And it does go quite a long way in making things work like they should.
cHao
@Jon: BTW, before you correct it, i mean "without locking or immutability". :)
cHao
Honestly all the answers helped me alot, but the link to that blog post really solved my problem... Thanks a million :)
KiNGPiN