为什么Java线程无法获取最新值

时间:2018-07-05 03:11:10

标签: java multithreading

我有一个简单的程序可以在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,至少打印值显示

0 个答案:

没有答案