多线程基础总结三--volatile
2010-01-22 00:00:00 来源:WEB开发网另外还有一个使用volatile的好处,得自于其原理:内部禁止改变两个volatile变量的赋值或者初始化顺序,并且严格限制volatile变量和其周围非volatile变量的赋值或者初始化顺序。
Java代码
/**
* User: yanxuxin
* Date: Dec 12, 2009
* Time: 8:34:07 PM
*/
public class VolatileTest {
public static void main(String[] args) {
final VolatileSample sample = new VolatileSample();
new Thread(new Runnable(){
public void run() {
sample.finish();
}
}).start();
new Thread(new Runnable(){
public void run() {
sample.doSomething();
}
}).start();
}
}
class VolatileSample {
private volatile boolean finished;
private int lucky;
public void doSomething() {
if(finished) {
System.out.println("lucky: " + lucky);
}
}
public void finish() {
lucky = 7;
finished = true;
}
}
这里首先线程A执行finish(),完成finished变量的赋值后,线程B进入方法doSomething()读到了finish的值为 true,打印lucky的值,预想状态下为7,这样完美的执行结束了。但是,事实是如果finished变量不是声明了volatile的话,过程就有可能是这样的:线程A执行finish()先对finished赋值,与此同时线程B进入doSomething()得到finished的值为 true,打印lucky的值为0,镜头切回线程A,接着给lucky赋值为7,可怜的是这个幸运数字不幸杯具了。因为这里发生了扯淡的事情:JVM或许为了优化执行把两者的赋值顺序调换了。这个结果在单线程的程序中简直绝对一定肯定就是不可能,遗憾的是多线程存在这个隐患。
所以不说其它的知识,想用Java实现正确,高性能的并发程序是需要处处小心的。后面想说的ThreadLocal就是看惯了线程为了共享数据而屡屡发生惨剧后,想把数据与线程死死绑定不共享的另一个技术。当然还想尝试写写对atomic包的理解,对并发集合的理解,对线程池的理解。所有的这些基础有个清晰的认识,才能有自信写写正确的,性能稍好的并发程序。
更多精彩
赞助商链接