Why are immutable objects thread-safe?

こ雲淡風輕ζ 提交于 2019-11-27 19:19:59

I think your question turns out not to be about thread-safety or immutablity but about the (very) low level details of memory access.

And that is a hefty subject but the short answer is: Yes, two threads (and more important, 2+ CPU's) can read (and/or write) the same piece of memory simultaneously.

And as long as the content of that memory area is immutable, all problems are solved. When it can change, there is a whole range of issues, the volatile keyword and the Interlocked class are some of the tools we use to solve those.

What makes an object not thread safe? An object is not thread safe if the value/state of that object can change while a thread is reading it. This generally happens if a second thread changes this object's value while the first thread is reading it.

An immutable object, by definition, cannot change value/state. Since every time you read an immutable object it has the same value/state, you can have any number of threads read that object with no concerns.

Simultaneous reads do not need synchronization. Since synchronization is only required for writers (or readers and at least one writer), immutable objects don't require synchronization, and are therefor threadsafe.

If the object is immutable its state will never change. Therefore the concerns of stale data go out the window. Thread reading is never locked in so this is a non-issue (deadlock)

Concurrent reads do not require synchronization in the vast majority of cases (exceptions are things like memory mapped IO where reading from a certain address can cause side effects).

If concurrent reads did require synchronization, it would be close to impossible to write usefully multi-threaded code. To execute a piece of code for instance, the processor has to read the instruction stream, how would you write a lock function if the function itself had to protect against itself being executed concurrently :)?

Reading the same memory location can only be done in one CPU cycle by a specific thread. The order of read in this case does not matter since the underlying value does not change. Therefore there is no possibility of a read being inconsistent, so there is no need of synchronization at any level in this case.

Memory Management Units are the part of the processor that handles the reading of memory. If you have more than one, once in a blue moon 2 of them might try to read the same memory location in the same dozen nano-seconds, but no problems result seeing as they get the same answer.

Besides exceptions like mapped memory for drivers for instance, There is no problem for two threads reading simultaneously the same memory address. A problem may arise when one thread performs some writing data though. In this case, other threads may be prevented to read that object/data.

But the problem is not due to the simultaneity of the writings (at the lowest electronic level they occur one after the other anyway), the problem is rather that the object / set of data may lose their consistency. Usually one utilize a section critic to isolate some code that may not be read/written simultaneously by other threads.

There are many examples over the Net, but consider the following, with price is a private member of a class, say Product, which has also 2 methods

public void setPrice(int value) {
  price = value;
  // -- point CRITIC --
  price += TAX;
}

public int getPrice() {
  return price;
}

setPrice(v) sets the price of a product to v, and adjust it with VAT (the program should have value += TAX; price = value but this is not the point here :-)

If thread A writes price 100, and TAX is (fixed) 1, the product price will finally be set to 101. But what happens if thread B reads the price via getPrice() while thread A is at point CRITIC? The price returned to B will miss the TAX, and be wrong.

setPrice() should within a critical section (lock), to prevent any access to the object during the setting of the price

    lock(this)
    {
      price = value;
      price += TAX;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!