When running the following code:
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public final class ThreadTest {
int N = 4;
Map<Integer, Proxy> proxy = Collections.synchronizedMap(new TreeMap<>());
Proxy p;
public static void main(String[] args) {
new ThreadTest();
}
public ThreadTest() {
Thread[] t = new Thread[N];
for(int c=0;c<N;c++) {
final int i = c;
t[i] = new Thread(() -> {
try {
System.out.println( "From thread: " + i );
p = new Proxy(i);
proxy.put(i, p);
p.init();
} catch (Exception e){}
});
t[i].start();
}
for(int c=0;c<N;c++) {
try {
t[c].join();
} catch (InterruptedException e){}
}
}
public class Proxy {
int index;
public Proxy(int index) {
this.index = index;
System.out.println( "Proxy: " + index );
}
public void init() {
System.out.println("Initializing " + index );
}
}
}
the printed indices from the method init() are not unique. The following is an example output:
From thread: 0
From thread: 1
From thread: 2
From thread: 3
Proxy: 0
Proxy: 3
Proxy: 2
Proxy: 1
Initializing 3
Initializing 3
Initializing 1
Initializing 2
Although I have synchronized the TreeMap with Collections.synchronizedMap(), the result is the same for an unsynchronized Map. This behavior seems quite odd considering it is just a put method and the index has changed completely. Could anybody please explain what is happening? Thanks.
Your problem is that your
pvariable is shared by all threads.From the prints in
init, it shows that this code block that thepvariable is written over by another thread beforeinitis called