假设:
>只有一个特定的线程可以设置某个参考字段(不是长或双,所以写入它是原子的)
>有任何数量的线程可能会读取相同的字段
>稍微过时的读数是可以接受的(最多几秒钟)
在这种情况下,您是否需要volatile或atomicreference或任何类似的东西?
This article状态:
Memory barriers are not required if you adhere strictly to the single writer principle.
这似乎表明,在我描述的情况下,你真的不需要做任何特别的事情.
所以,这是一个有好奇的结果的测试:
import org.junit.Test; public class ThreadTest { int onlyWrittenByMain = 0; int onlyWrittenByThread = 0; @Test public void testThread() throws InterruptedException { Thread newThread = new Thread(new Runnable() { @Override public void run() { do { onlyWrittenByThread++; } while (onlyWrittenByMain < 10 || onlyWrittenByThread < 10); System.out.println("thread done"); } }); newThread.start(); do { onlyWrittenByMain++; // Thread.yield(); // System.out.println("test"); // new Random().nextInt(); } while (onlyWrittenByThread < 10); System.out.println("main done"); } }
有时运行它会输出“线程完成”,然后永久挂起.有时它完成.所以线程看到主线程所做的更改,但显然main并不总是看到线程所做的更改
如果我把系统放在,或者Thread.yield中,或是随机调用,或者只做WrittenByThread volatile,它每次都会完成(尝试10次).
这是否意味着我上面引用的博文不正确?即使在单一作家场景中,您也必须拥有记忆障碍?
没有人相当回答这个问题,所以我想我会猜测,内存障碍不是必需的可能是正确的,但没有什么可以创造发生之前的关系,java编译器和热点可以做优化(例如提升)会使它不做任何想要的.
解决方法
原文地址:https://www.jb51.cc/java/126411.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。