Multithreading 如何使用多线程java处理volatile

Multithreading 如何使用多线程java处理volatile,multithreading,volatile,Multithreading,Volatile,Volatile提供对程序内存的读写,绕过缓存。当存在一个公共资源(例如整数变量)时,我们应该使用volatile 所以,我做了一个小实验。 首先,我上了以下课程: public class Main3 { static int j = 0; public static void main(String[] args) throws InterruptedException { new Thread1().start(); new Thread2(

Volatile提供对程序内存的读写,绕过缓存。当存在一个公共资源(例如整数变量)时,我们应该使用volatile 所以,我做了一个小实验。 首先,我上了以下课程:

public class Main3 {
    static int j = 0;
    public static void main(String[] args) throws InterruptedException {
        new Thread1().start();
        new Thread2().start();
    }
    static int i = 0;
    static class Thread1 extends Thread{
        @Override
        public void run() {
            while(i<5){
                System.out.println("thread1 i = "+i);
                i++;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    static class Thread2 extends Thread{
        @Override
        public void run() {
            int val = i;
            while(val<5){
                if(val!=i) {
                    System.out.println("thread2 i = " + i);
                    val = i;
                }
            }
        }
    }
}
但是,如果我这样做(将睡眠添加到Thread2类):


那么,如果线程缓存值,那么为什么睡眠缓存会随着睡眠的出现而消失呢?

您是否调试并检查了它是否不是一种竞争条件?例如,“当存在公共资源时,我们应该使用
volatile
。”不可以。我们不应该使用volatile,除非我们在编写多线程代码方面非常熟练,不再需要询问。在那之前,我们应该从
synchronized
块中访问共享资源。是的,是的,但我的问题是它为什么这样工作?它之所以这样工作,是因为它被允许这样工作。我假设您的示例中是Java代码。《Java语言参考手册》列出了一些关于如果您遵守某些规则,多线程程序将如何运行的承诺,但没有说明如果您的程序违反规则会发生什么。FWIW,这就是为什么几乎不可能编写软件测试来捕获线程同步错误的原因。如果某个程序在某一天、某一特定硬件平台、某一特定操作系统上通过了测试,则该程序可能会在另一天/box/OS.P.S.失败。每当线程从
sleep()
返回时,操作系统可能会使它选择运行
Thread2
的任何处理器的处理器缓存失效。但是,你永远不应该依靠它以这种方式工作。
thread1 i = 0
thread1 i = 1
thread1 i = 2
thread1 i = 3
thread1 i = 4
static class Thread2 extends Thread{
        @Override
        public void run() {
            int val = i;
            while(val<5){
                if(val!=i) {
                    System.out.println("thread2 i = " + i);
                    val = i;
                }
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
thread1 i = 0
thread2 i = 1
thread1 i = 1
thread2 i = 2
thread1 i = 2
thread2 i = 3
thread1 i = 3
thread2 i = 4
thread1 i = 4
thread2 i = 5