java多线程并发问题


public class TestMain {
    private static int index = 0 ;
    public static void main(String[] args) {
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (true){
                index++;
            }
        }).start();
        new Thread(()->{
            int temp = index;
            while (true){
                if(temp!=index){
                    System.out.println(index);
                    temp = index;
                }
            }
        }).start();
    }
}

描述:线程1对共享变量index执行++操作,线程2循环去判断index的值是否变化,测试后发现,
情况1:当第线程1中有Thread.sleep(100)时,线程2无法检测到index的值变化,死循环无输出,结果与预计的一致,
情况2:但是注释掉Thread.sleep(100)后,线程2会输出部分后进入死循环。
按照可见性的说法,由于index不是线程安全的,线程2在判断时的取值没有去主内存取最新的值。应该与Thread.sleep(100)没有关系,为什么去掉后反而检测到了部分值变化?

其实从你描述的来说,你这个和线程安全关系不大,你这个和CPU时间片有关,你线程1中有没有Thread.sleep(100)关系不大,主要是 while (true){index++;}这代码。这个线程在执行这个死循环时,它会一直占用CPU,根本不会切换到线程2执行,如果你添加输出或者sleep就能看出效果。while (true){System.out.println(index);index++;}。

简单来说,就是你线程A往杯子里倒水,线程B检测杯子水的量。但是你线程A一直占用杯子,B根本没拿到杯子
而当你线程A中有Thread.sleep(100)时,是线程B先拿到杯子,所以在BSystem.out的瞬间A有机会拿到杯子,如果B没有这句,可能A也没机会
只有等时间片切换才能切换杯子的所有权

两周情况在我电脑都没复现,可能我核数比较多16C