我有一个简单的程序可以在Java中测试多线程
public class Test {
public static void main(String[] args) {
final Data data = new Data();
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
public void run() {
for (int j = 0; j < 5; j++) {
data.set(new Random().nextInt(30));
}
}
}).start();
}
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
public void run() {
for (int j = 0; j < 5; j++) {
data.get();
}
}
}).start();
}
}
}
class Data {
private int data;
public void set(int data) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ready to write data");
this.data = data;
System.out.println(Thread.currentThread().getName() + " write " + this.data);
}
public void get() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ready to read data");
System.out.println(Thread.currentThread().getName() + " read " + this.data);
}
}
结果是随机的,而一次,我得到了这样的结果:
Thread-3 ready to read data
Thread-2 ready to write data
Thread-1 ready to write data
Thread-0 ready to write data
Thread-0 write 20
Thread-4 ready to read data
Thread-1 write 10
Thread-5 ready to read data
Thread-2 write 10
Thread-3 read 0
Thread-5 read 20
Thread-4 read 20
etc
我对此感到困惑,所有线程都共享Data类中的data变量,而最后一次写操作是Thread-2写10,我认为数据值现在应该是10,为什么Thread-3读0 ,线程5和线程4读20?我认为他们应该读10
同时,您是对的,我应该为数据变量添加volatile,但之后,结果将变为:
Thread-0 ready to write data
Thread-2 ready to write data
Thread-3 ready to read data
Thread-1 ready to write data
Thread-5 ready to read data
Thread-5 read 22
Thread-3 read 16
Thread-4 ready to read data
Thread-2 write 16
Thread-0 write 22
etc
为什么读取操作可以先于写入操作,为什么在写入之前先读取22和16,至少打印值显示