I have this class:
class S2Es2SharedState {
public int x;
public int y;
}
that is used to share an s2Es2SharedState object in every thread inside in the loop:
class S2Es2Worker implements Runnable {
private final int id;
private S2Es2SharedState state;
private final int delay;
private int numErrors = 0;
public S2Es2Worker(final int id, final S2Es2SharedState state,
final int delay) {
this.state = state;
this.delay = delay;
this.id = id;
this.numErrors = 0;
System.out.println("Worker " + id + ": created with " + delay
+ " ms delay");
}
@Override
public void run() {
boolean check = true;
System.out.println("Worker " + id + ": started");
for (int i = 0; i < 150; i++) {
state.x++;
try {
Thread.sleep(delay);
} catch (final InterruptedException e) {
// do nothing
}
state.y++;
}
}
}
in this program working 10 threads where each of them enter in the loop and increment 150 times the value of x and y of the shared object, so the final result in the x and y of the shared object is 1500.
If i don't change anything this program have a problem of race condition, so for fix this problem i used the lock (and it works).
But now i want to fix the problem of the race condition using the immutable object instead of the locks. so i changed the class of the shared object in this way:
final class S2Es2SharedState {
private final int x;
private final int y;
public S2Es2SharedState(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public S2Es2SharedState incrementX() {
return new S2Es2SharedState(x+1, y);
}
public S2Es2SharedState incrementY() {
return new S2Es2SharedState(x, y+1);
}
}
and in the run() method i changed the state variable in this way:
class S2Es2Worker implements Runnable {
....
private volatile S2Es2SharedState state;
....
and in the for loop i did this edit:
for (int i = 0; i < 150; i++) {
state = state.incrementX();
try {
Thread.sleep(delay);
} catch (final InterruptedException e) {
// do nothing
}
state = state.incrementY();
}
}
But i don't know why the final result is that the shared object has instead of x=1500 and y=1500
150 in both variable
How can i fix the problem with the race of condition using the immutable object?
I'm going to assume you create a S2Es2SharedState
(use simpler names for asking questions) as
S2Es2SharedState state = new S2Es2SharedState(0, 0)
and passing it to the S2Es2Worker
instances something like
for (int i = 0; i < 10;i++) {
S2Es2Worker worker = new S2Es2Worker(i, state, 5);
new Thread(worker).start();
}
In java, everything is passed by value. So the using state
as a method argument, a copy of the value of the reference is passed.
So the field
private volatile S2Es2SharedState state;
is also referencing the same object. However, if you change the reference that the field state
is holding, for example with
state = state.incrementX();
that doesn't affect any other references.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.