简介:
这是检验多线程可见性(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这个关键字的问题。。。