How instances of immutable types are inherently thread safe

I am looking about why .NET String is immutable? And got this answer:

Instances of immutable types are inherently thread safe, since no thread can change it, the risk of changing the thread in such a way that it overwrites with another is deleted (the reference itself is matter).

So I want to know, how are instances of immutable types inherently thread safe?

+3


source to share


3 answers


Why are instances of immutable types inherently thread safe?

Since a type instance string

cannot be mutated across multiple threads. This effectively means that one thread that changes the value string

will not cause the same string

thread to be changed in another thread, since a new one string

is allocated at the place where the mutation occurs.

It usually gets easier when you create an object once and then only observe it. After you need to change it, a new local copy is created.

Wikipedia :



Continuous objects can be useful in multi-threaded applications. Multiple threads can act on data represented by immutable objects without regard to data that is modified by other threads. Immutable therefore objects are considered more thread safe than mutable objects.

@xanatos (and wikipedia) point out that immutable is not always thread safe. We like to do this correlation because we say that "any type that has a persistent immutable state is thread-safe," but it might not always be. Suppose a type is "immutable" from "external", but internally would have to change its state in a way that could be unsafe if executed in parallel from multiple threads, and could cause undefined behavior. This means that although immutable, it is not thread safe.

In conclusion, immutable! = Thread safe. But immutability takes you one step closer, when done right, to be able to do multi-threaded work right.

+5


source


The short answer is:

Because you only write data to 1 thread and always read it after writing in multiple threads. Since a read / write conflict is not possible, it is thread safe.

Long answer:

A string is essentially a pointer to a memory buffer. What basically happens is that you create a buffer, fill it with characters, and then expose a pointer to the outside world.

Note that you cannot access the contents of the string before the string object has been instantiated, which ensures that this "write data" ordering is done and then the "pointer". If you do it the other way around (I think this is theoretically possible), problems can arise.

If a pointer is read on another thread (say: CPU), it is a "new pointer" for the CPU, so it requires the CPU to go into "real" memory and then read the data. If it takes the contents of the pointer from the cache, we'd have a problem.



The last piece of the puzzle is about memory management: we need to know it as a "new" pointer. In .NET, we know this to be the case: memory on the heap is basically never reused until a GC happens. The garbage collector then makes a mark, waves and compacts.

Now you can argue that the "compact" phase repeats pointers, so the contents of the pointers change. While this is true, the GC must also stop the threads and force full memory fetching, which in simple terms clears the processor cache. Memory access is then guaranteed, which ensures that you always have to jump into memory after the GC phase ends.

As you can see, there is no way to read the data without reading it directly from memory (as it was written). Since it is immutable, the content remains the same for all threads until it is collected. Thus, it is thread safe.


I've seen some discussion about immutability here, which suggests that you can change the internal state. Of course, the moment you start to change, you can potentially imagine read / write conflicts.

The definition of what I'm using here is to keep the contents of the constant after creation. That is: write once, read a lot, do not change (any) state after pointer exposure. You get the picture.

+2


source


One of the biggest problems in multithreaded code is two threads accessing the same memory location at the same time, with at least one of them modifying that memory location.

If none of the threads can change the memory location, the problem no longer exists.

Since an immutable variable is not modified, it can be used from multiple threads without any additional measures (such as locks).

+1


source







All Articles