关于synchronized是否能保证可见性。

来源:互联网 发布:手机魔音软件下载 编辑:程序博客网 时间:2024/05/21 06:50

在文章http://blog.csdn.net/taotao4/article/details/42744871中有验证过volatile可见性,早上起来觉得java中常用的同步关键字synchronized没有明确提过是否能保证可见性。猜测synchronized关键字,不能作为可见性的保证,于是修改了上一篇博客的代码验证一下,只是在t1线程中增加了synchronized关键字

代码如下:

 

package com.easy;public class Main {public static Integer max = 100;public static void main(String[] args){Thread[] threads = new Thread[20];for (int i = 0; i < threads.length; i++) {            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                                        while (true) {                    if(max == null ){                    max = 10;                    System.out.println("已经被重置为null");                    }                    }                }            });            threads[i].start();        }try {Thread.sleep(10000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}Thread t1 = new Thread(){public void run(){while(true){//System.out.println("重置中");synchronized(this){max = null;}}}};t1.start();}}
代码的执行结果是永远看不到“已经被重置”这段话的输出。也就是后面t1线程max=null的结果,对上面thread[i]中每一个线程都不可见。

再次引用文章:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#incorrectlySync

这里提到synchronized会保证对进入同一个监视器的线程保证可见性。比如线程th1修改了变量,退出监视器之前,会把修改变量值v1刷新的主内存当中;当线程t2进入这个监视器时,如果有某个处理器缓存了变量v1,首先缓存失效,然后必须重主内存重新加载变量值v1(这点和volatile很像)。这里语义的解读只是说了对于同一个监视器,变量的可见性有一定的方式可寻,非同一个监视器就不保证了。


本文的代码示例不符合同一个监视器的条件,所以有这不可见也就正常了。

测试平台:

os x 10.10.2 

cpu i5

java version "1.7.0_71"

Java(TM) SE Runtime Environment (build 1.7.0_71-b14)

Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)



0 0
原创粉丝点击