The following is transferred from http://ifeve.com/thread-safety-and-immutability/:
A race condition occurs when multiple threads access the same resource at the same time, and one or more of the threads writes to the resource. Multiple threads reading the same resource at the same time will not produce a race condition.
We can achieve thread safety by creating immutable shared objects to ensure that objects are shared between threads without modification. The following example:
Public class immutablevalue{ privateint value = 0; Public Immutablevalue (int value) { this. Value = value; } Public int GetValue () { returnthis. value; }}
Note that the member variables of the Immutablevalue class value
are assigned by constructors and do not have a set method in the class. This means that once the Immutablevalue instance is created, the value
variable can no longer be modified, which is immutability. But you can read the value of this variable by using the GetValue () method.
(Translator Note: Note that the "invariant" (immutable) and "Read Only" (read only) are different. When a variable is "read-only", the value of the variable cannot be changed directly, but it can change when other variables change. For example, a person's date of birth is a "constant" attribute, and a person's age is a "read only" attribute, but is not the "invariant" attribute. As time changes, the age of one person changes, and the day of birth of a person does not change. This is the difference between "unchanging" and "read-only". (Excerpt from chapter 34th Java and Patterns))
If you need to manipulate an instance of the Immutablevalue class, you can do so by creating a new instance after the value variable is obtained, and here is an example of an addition to the value variable:
Public classimmutablevalue{Private intValue = 0; PublicImmutablevalue (intvalue) { This. Value =value; } Public intGetValue () {return This. Value; } PublicImmutablevalue Add (intValuetoadd) { return NewImmutablevalue ( This. Value +Valuetoadd); }}
Note that the Add () method returns the result of the addition operation as a new instance of the Immutablevalue class, rather than directly manipulating its own value variable.
References are not thread safe!
It is important to remember that even if an object is a thread-safe immutable object, references to that object may not be thread-safe. See this example:
Public voidcalculator{PrivateImmutablevalue CurrentValue =NULL; PublicImmutablevalue GetValue () {returnCurrentValue; } Public voidSetValue (Immutablevalue newvalue) { This. CurrentValue =NewValue; } Public voidAddintnewvalue) { This. CurrentValue = This. Currentvalue.add (NewValue); }}
The Calculator class holds a reference to the Immutablevalue instance. Note that this reference may be changed by the SetValue () method and the Add () method. Therefore, even though an immutable object is used inside the calculator class, the Calculator class itself is mutable, so the calculator class is not thread-safe. In other words: The Immutablevalue class is thread-safe, but the class that uses it is not. This is something to keep in mind when trying to get thread safety through immutability.
For the calculator class to be thread-safe, declare the GetValue (), SetValue (), and Add () methods as synchronous methods (the next section explains).
Java Multithreading-Thread safety and immutability