线程的未解之谜

简介:

这是检验多线程可见性(volatile关键字)的时候发现的问题。请不要再循环中使用System.out.println();这种代码,因为他是被synchronized修饰的,所以没法用来检测。有没有大神能解释一下,下面这些案例是什么鬼???请不要说加volatile、synchronized能解决这种情况,这个应该大家都知道。我只想知道为什么会出现在下面这几个案例的情况。。。

案例一:

运行时线程没法结束,debug的时候线程1就能结束( f = isF中打断点)???

class mythread_volatile2 implements Runnable {
    public boolean isF = true;

    @Override
    public void run() {
        boolean f = isF;
        while (f) {
            f = isF;
        }
        System.out.println(Thread.currentThread().getName() + "线程结束");
    }
}

public class Test_volatile2 {
    public static void main(String[] args) throws InterruptedException {
        mythread_volatile2 m = new mythread_volatile2();
        Thread t1 = new Thread(m, "线程1");
        t1.start();
        Thread.sleep(100);
        m.isF = false;
        Thread.sleep(2000);
        System.out.println("aaaaaa");
    }
}

案例二:

将案例一种的循环中加入线程休眠一秒钟,然后运行,发现线程1就能结束了???

class mythread_volatile2 implements Runnable {
    public boolean isF = true;

    @Override
    public void run() {
        boolean f = isF;
        while (f) {
            f = isF;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "线程结束");
    }
}

public class Test_volatile2 {
    public static void main(String[] args) throws InterruptedException {
        mythread_volatile2 m = new mythread_volatile2();
        Thread t1 = new Thread(m, "线程1");
        t1.start();
        Thread.sleep(100);
        m.isF = false;
        Thread.sleep(2000);
        System.out.println("aaaaaa");
    }
}

案例三:

可能有些人会说没有用volatile修饰,线程之间本来就是不可见的,那请看一下这个案例,你可以去执行一下。。。如果说一直都是不可见的(也就是说一直都没有去刷新主内存,或者没有去读取最新的主内存),那这个案例的最后结果输出的就是3个100。

class mythread_volatile implements Runnable {
    int isF = 0;
    public int i = 0;
    public int j = 0;

    @Override
    public void run() {
        while (isF <= 100) {
            if (Thread.currentThread().getName().equals("线程1")) {
                i = i + 1;
            } else {
                j = j + 1;
            }
            isF = isF + 1;
        }
    }
}

public class Test_volatile {
    public static void main(String[] args) throws InterruptedException {
        mythread_volatile m = new mythread_volatile();
        Thread t1 = new Thread(m, "线程1");
        Thread t2 = new Thread(m, "线程2");
        t1.start();
        t2.start();
        Thread.sleep(10000);
        System.out.println(m.isF + "   " + m.i + "   " + m.j);
    }
}

猜想:

1、可能是主线程中的本地内存没有刷新到主内存中,但是debug的时候又能结束,所以这种猜想是不科学的。

2、主线程中的本地内存刷新到主内存中了,可能是线程1读取的是本地线程,没有去读取主内存,但是在循环中加入休眠一秒又能结束线程。

3、也可能是while这个关键字的问题。。。

猜你喜欢

转载自blog.csdn.net/tuesdayma/article/details/81237226