Consider the following example:
package thread;
public class ThreadVerify {
public static boolean stop = false;
public static void main(String args[]) throws InterruptedException {
Thread testThread = new Thread(){
@Override
public void run(){
int i = 1;
while(!stop){
//System.out.println("in thread: " + Thread.currentThread() + " i: " + i);
i++;
}
System.out.println("Thread stop i="+ i);
}
};
testThread.start();
Thread.sleep(1000);
stop = true;
System.out.println("now, in main thread stop is: " + stop);
testThread.join();
}
}
The working thread is started to do increment on i and after one second, the flag is set as true in main thread. It is expected that we could see print out in working thread: “Thread stop i=”. Unfortunately it is NOT the case. Through process explorer we can find the working thread is still running:
The only way we can terminate it is to click this button in Eclipse:
The reason is: every thread in Java has its own thread local stack in runtime. Every time a thread tries to access the content of a variable, it first locates the variable content in the main memory, then loads this content from main memory to its local stack. Once this load is done, this relationship between thread local stack and main memory is cut.
Later, when thread performs modifications on the variable, the change is directly done on thread local stack. And at a given time ( scheduled by JVM, developer has no control about this timeslot), the change will be refreshed from thread local stack to memory. Back to our example, already the main thread has changed the flag to true in one second later ( this is TOO late! ), unfortunately when the working thread reads the flag from its own local stack, the flag is still false ( it makes sense since when it is copied from main memory in main thread ), so the working threads could never end. See the following picture for detail.
Solution is: add keyword volatile to flag variable, to force the read access on it in working thread is done always from main memory, so that after the flag is changed to true in main thread, later the working thread can detect this latest change since it reads data from main memory now. After this keyword is added we can get expected output:
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
相关推荐
java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java ...
主要讲述java线程volatile关键字
java volatile 关键字 学习
【Java面试题】volatile的作用
从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性
Java并发编程:volatile关键字解析
violate java_Java 之 volatile 超级详解
主要介绍了Java Volatile 变量详解及使用方法的相关资料,需要的朋友可以参考下
java语言的volatile教程,java语言的volatile关键字到底怎么用
主要介绍了java volatile关键字使用方法及注意事项的相关资料,当一个变量被声明为 volatile 后,java 内存模型确保所有使用该变量的线程能看到相同的、一致的值。,需要的朋友可以参考下
Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;
在本文里我们给大家分享的是关于java volatile关键字作用及使用场景的相关知识点内容,需要的朋友们学习下。
synchronized是阻塞式同步,在线程...这个实际对普通变量没有规定的,而针对volatile修饰的变量给Java虚拟机特殊的约定,线程对volatile变量的修改会立刻被其他线程所感知,即不会出现数据脏读,从而保证数据的可见性。
volatile是java中的关键词之一,这篇文章主要给大家介绍了关于Java中volatile关键字的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 ...
java里的volatile关键字详解
Java基础:volatile详解