java内存模型学习笔记

来源:互联网 发布:虚拟现实制作软件 编辑:程序博客网 时间:2024/06/06 19:13

1·数据争用问题。
引用自JSR133
光看图可能很难理解什么意思,这里表示的是程序可能执行的两种顺序,我们一般会觉得a这种情况是正确的程序执行方式,但是在多线程的程序中,a和b这种情况都有可能出现,还可能出现别的情况,这就出现了数据争用的问题。

我写了一个测试程序来说明这种情况。

代码:

package com.test;import java.util.concurrent.locks.ReentrantLock;/** * Created by zhongzhong on 2016/11/6. */public class LockDemo {    public static int x = 0;    public static int y = 0;    public static int r = -1;    public static int r2 = -2;    ReentrantLock lock = new ReentrantLock();    class Thread1 implements Runnable{        public void run() {            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->start");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            x = 1;            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->x=1 end.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->lock start.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            lock.lock();            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->y=1 start.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            y = 1;            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->y=1 end.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            lock.unlock();            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t1--->unlock end.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);        }    }    class Thread2 implements Runnable{        public void run() {            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t2--->start");            System.out.println("t2--->lock start.");            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            lock.lock();            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t2--->r=y start.");            r=y;            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t2--->r=y end.");            lock.unlock();            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t2--->unlock end.");            System.out.println("t2--->r2=x start.");            r2=x;            System.out.println("x="+x+",y="+y+",r="+r+",r2="+r2);            System.out.println("t2--->r2=x end.");        }    }    public void test(){        new Thread(new Thread1()).start();        new Thread(new Thread2()).start();    }    public static void main(String[] args) {        new LockDemo().test();    }}

我们来看这段代码执行几次的结果和输出记录:

1。

x=0,y=0,r=-1,r2=-2t1--->startx=0,y=0,r=-1,r2=-2x=1,y=0,r=-1,r2=-2t1--->x=1 end.x=1,y=0,r=-1,r2=-2t1--->lock start.x=1,y=0,r=-1,r2=-2x=1,y=0,r=-1,r2=-2t1--->y=1 start.x=1,y=0,r=-1,r2=-2t2--->startt2--->lock start.x=1,y=0,r=-1,r2=-2x=1,y=0,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t1--->y=1 end.x=1,y=1,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t1--->unlock end.x=1,y=1,r=-1,r2=-2t2--->r=y start.x=1,y=1,r=1,r2=-2t2--->r=y end.x=1,y=1,r=1,r2=-2t2--->unlock end.t2--->r2=x start.x=1,y=1,r=1,r2=1t2--->r2=x end.x=1,y=1,r=-1,r2=-2

2。

x=0,y=0,r=-1,r2=-2t1--->startx=0,y=0,r=-1,r2=-2x=1,y=0,r=-1,r2=-2t1--->x=1 end.x=1,y=0,r=-1,r2=-2t1--->lock start.x=1,y=0,r=-1,r2=-2x=1,y=0,r=-1,r2=-2t1--->y=1 start.x=1,y=0,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t1--->y=1 end.x=1,y=1,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t1--->unlock end.x=1,y=1,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t2--->startt2--->lock start.x=1,y=1,r=-1,r2=-2x=1,y=1,r=-1,r2=-2t2--->r=y start.x=1,y=1,r=1,r2=-2t2--->r=y end.x=1,y=1,r=1,r2=-2t2--->unlock end.t2--->r2=x start.x=1,y=1,r=1,r2=1t2--->r2=x end

要重现上图中的效果还是比较困难,但上面两种结果就足以说明这段程序是有数据争议的,在两个线程同时运行时,就会出现无法预期的结果。

0 0
原创粉丝点击