加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 如果你只有一个写线程,你有没有需要特殊的并发?

发布时间:2020-12-15 00:24:21 所属栏目:Java 来源:网络整理
导读:假设: 只有一个特定的线程可以设置某个参考字段(不是长或双,所以写入它是原子的) 有任何数量的线程可能会读取相同的字段 稍微过时的读数是可以接受的(最多几秒钟) 在这种情况下,您是否需要volatile或AtomicReference或任何类似的东西? This article状态:
假设:

>只有一个特定的线程可以设置某个参考字段(不是长或双,所以写入它是原子的)
>有任何数量的线程可能会读取相同的字段
>稍微过时的读数是可以接受的(最多几秒钟)

在这种情况下,您是否需要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编译器和热点可以做优化(例如提升)会使它不做任何想要的.

解决方法

问题是在多核系统上缓存 – 没有像volatile这样的挥发性强制强制发生的关系(内存障碍物),你可以让你的写作线程写入缓存中的变量的副本在其核心,所有读者线程读取另一个在另一个核心上复制变量.另一个问题是Atomicity,另一个答案就是这样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读