并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”。从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CPU对共享资源的访问,因此需要了解并发,穷矮搓搞优化需要编写各种多线程的代码来压榨CPU的计算资源,让它在同一时刻做更多的事情,这个更需要了解并发。
在我前一篇关于并发的文章http://my.oschina.net/chihz/blog/54731中提到过管程,管程的特色是在编程语言中对并发的细节进行封装,使程序员可以直接在语言中就得到并发的支持,而不必自己去处理一些像是控制信号量之类容易出错且繁琐的细节问题。一些语言是通过在编译时解开语法糖的方式去实现管程,但Java在编译后生成的字节码层面上对并发仍然是一层封装,比如syncrhonized块在编译之后只是对应了两条指令:monitorenter和monitorexit。更多的并发细节是在JVM运行时去处理的,而不是编译。这篇文章主要是针对JVM处理并发的一些细节的探讨。
JAVA内存模型
内存可见性
1
|
boolean open= true;
|
1
2
3
4
|
//线程A
resource.close();
open = false;
|
1
2
3
4
5
|
//线程B
while(open) {
doSomethingWithResource(resource);
}
|
指令重排序
1
2
|
private int a;
private int b;
|
1
2
|
a = 1;
b = 2;
|
1
2
|
b = 2;
a = 1;
|
1
2
|
context = loadContext();
inited = true;
|
1
2
3
4
|
while(!inited ){
sleep
}
doSomethingwithconfig(context);
|
1
2
|
inited = true;
context = loadContext();
|
最后的总结
这篇文章简单的介绍了Java内存模型、内存可见性和指令重排序。不过最后看来其实主要是在解释volatile这个关键字,个人感觉volatile关键字是Java当中最令人困惑和最难理解的关键字。相对于synchronized块的代码锁,volatile应该是提供了一个轻量级的针对共享变量的锁,当我们在多个线程间使用共享变量进行通信的时候需要考虑将共享变量用volatile来修饰,对于需要使用volatile的各种情景,看到IBM Developer Works上有一篇文章总结的很不错,推荐一下: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html