java-利用synchronized实现volatile的功能

来源:互联网 发布:淘宝怎么预约快递 编辑:程序博客网 时间:2024/06/07 02:24
/** * Created by Dev_yang on 2016/4/23. */public class ThreadLock2 {    public static void main(String[] args) {        Service service = new Service();        ThreadA threadA = new ThreadA(service);        threadA.start();        ThreadB threadB = new ThreadB(service);        threadB.start();        System.out.println("已经发起停止命令!");    }}class Service {    private boolean flag = true;    void run() {        while (flag) {        /*   取消这里的注释即可解决线程间数据不可见问题         synchronized (Service.class){            }*/        }        System.out.println("service stop run!");    }    void changeFlag() {        flag = false;    }}class ThreadA extends Thread {    private Service service;    public ThreadA(Service service) {        this.service = service;    }    @Override    public void run() {        service.run();    }}class ThreadB extends Thread {    private Service service;    public ThreadB(Service service) {        this.service = service;    }    @Override    public void run() {        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        service.changeFlag();    }}

“`这里写图片描述
出现上面现象的原因是因为threadB 线程对于 flag = false;的执行结果对于 线程threadA而言是看不见的,因为每个线程对于变量的读取(第一次读取变量会从主内存读取,第二次就会直接从私有内存读取)或者更改都只会在自己的私有内存当中生效,当该线程执行完自己的代码逻辑时才会将结果刷新到主内存中(为了提高线程执行效率),所以threadA读取的一直就是自己的缓存flag=true的值,因此System.out.println(“service stop run!”);这段代码一直无法被执行,程序陷入死循环。

解决办法:将程序代码中while循环的注释取消,即可让System.out.println(“service stop run!”);得到执行。

解释:synchronized 具有和vilatile相似的功能,当变量的值被修改后,线程私有内存缓存的值会失效,强制其前往主内存中再次读取,当然其对变量值得修改也是立马被刷新到主内存当中

0 0
原创粉丝点击