首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java多线程初始-原子性可见性hanppened-before原则

2012-09-19 
java多线程初步-原子性可见性hanppened-before原则在看《how works tomcat》时穿插看了《Java多线程并发编程

java多线程初步-原子性可见性hanppened-before原则

在看《how works tomcat》时穿插看了《Java多线程并发编程实现》,现在俩本书都渐入尾声...

《Java多线程并发编程实现》觉得理解的还不够,准备看第二遍,然后再看看《java并发编程:设计原则与模式》..《how works tomcat》准备结合源码,尝试编写简单的web服务器,这个周期会很长,给自己定的半年的时间吧..

分享下看书的心得把,我觉得写博客是很好的学习方式,不再拿书上的例子,例子全部为自己重写,这样才能引发更多的思考。


看下面这个例子,Plane是一个存储飞机状态的类,它有俩个状态变量想想x,y来表示其坐标,Diasphater线程会不停轮流调用Plane的move1方法,和move2方法,Renderer类会根据Plane的状态渲染出这个Plane,我们期望的状态是Plane会在(2,2), (3,3)上不停渲染,而不会出现在(2,3),(3,2)上,但结果是令人失望的。


这个类看似充分进行了同步?我想细心点的大家很容易就能发现其中的问题。

public class Five {    private static float money = 0;    private static boolean isObey = true;    public static void main(String[] args) {        new FiveCent().start();        isObey = false;        money = 0.5f;    }       static class FiveCent extends Thread {        @Override        public void run() {            while (!isObey) {                Thread.yield();            }            System.out.println("社会主义好 == " + money);        }    }}

有可能(虽然非常难以重现)程序会输出了 "社会主义好 ==0.5“ ,这说明在FiveCent运行的那个线程中看到了主线程对money的写入操作money =0.5f ,却没有看到对isObey的写入操作,isObey=false,这就是重排序问题,此时我们可以使用恰当的同步来抑制重排序...

(2)同一个锁的 unlock happened-before lock

(3)传递性,如果A happened-before B , B happened-before C,那么A happened-before C

好了,有了这三条原则已经可以解释很多多线程问题了,现在结合这3条原则来解释那个一定会的问题。

首先,Dispatcher线程先获得Plane的内部锁也就是lock,然后对x,y进行写操作,然后unlock, 这是在一个线程内发生的符合原则一。可以得出对x,y的写操作happened-beforeunlock。

然后,getY()得到Plane的内部锁lock,然后是一个对y的读操作,然后unlock。根据原则一可以得到 lock  happened-before y的读操作,根据原则二得到 unlocak happened-before lock,再根据原则三也就是传递性得到,对x,y的写操作 happened-before y的读操,也就是说,x,y的写操作一对会被y的读操作正确观测到,这就解释了一定会的问题。


有了基本的概念,下篇文章会说下如何构建线程安全的类。


热点排行