这里需要挥发性吗?

发布于 2024-12-28 06:42:18 字数 739 浏览 3 评论 0原文

在以下假设场景中,出于更好地理解语言的愿望,int[] 引用是否需要 volatile?

public final class SO {

    private int[] ar = new int[10];  // is volatile needed here?
    private int idx = 0;

    public synchronized int get( int i ) {
        return ar[i];
    }

    public synchronized void append( final int val ) {
        if ( idx == ar.length ) {
            // array is too small, let's grow it
            final int[] prev = ar;
            ar = new int[ar.length+ar.length*20/100]
            System.arrayCopy(prev, 0, ar, 0, prev.length);
        }
        ar[idx++] = val;
    }

}

检索int的唯一方法是通过同步方法,也是修改int[]的唯一方法(包括创建一个新的 >int[]) 也是通过同步方法完成的。

我不需要添加任何额外的同步,对吧?

In the following hypotetical scenario and out of desire to better understand the language, is volatile required for the int[] reference?

public final class SO {

    private int[] ar = new int[10];  // is volatile needed here?
    private int idx = 0;

    public synchronized int get( int i ) {
        return ar[i];
    }

    public synchronized void append( final int val ) {
        if ( idx == ar.length ) {
            // array is too small, let's grow it
            final int[] prev = ar;
            ar = new int[ar.length+ar.length*20/100]
            System.arrayCopy(prev, 0, ar, 0, prev.length);
        }
        ar[idx++] = val;
    }

}

The only way to retrieved an int is trough a synchronized method and the only way to modify the int[] (including creating a new int[]) is also done trough a synchronized method.

I do not need to add any additional synchronization right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我的影子我的梦 2025-01-04 06:42:18

不,不需要易失性,因为它只能在同步方法内访问,因此它已经是线程安全的。您的代码中不需要进一步的线程安全。

No, volatile not needed because it is only accessed inside synchornised methods so it is already thread safe. No further thread safety is needed in your code.

流心雨 2025-01-04 06:42:18

就像你说的那样,因为 int 受到类锁的保护 - 但它会很慢,因为写和读访问会互相阻塞。 (有关更快的方法,请参阅 CopyOnWriteList 实现)

it will would just like you said since the int is protected by the class lock - but it will be dog slow, since write and read access block each other. (see CopyOnWriteList implementation for a faster way)

夕色琉璃 2025-01-04 06:42:18

根据 java lang 规范
使用 易失性为线程添加严格的规则(从主内存读/写),使用同步则可以放松一点。

As per java lang specfication
having volatile add strict rules for threads(read/write from main memory), using synchronized relaxes on that little bit.

深者入戏 2025-01-04 06:42:18

你没问题,除非你的值在其他地方被访问而没有同步。

顺便说一句,如果您确实使 ar 易失性 而不是使用同步方法,那么您也需要使 idx 易失性。但这仍然不够同步,因为同时运行 append 的两个不同线程可能会造成严重破坏。

实际上,使用易失性数组还存在另一个问题:更改数组中的值不会触发缓存同步。只有重新分配数组(就像创建更大的数组时所做的那样)才会触发缓存刷新。

You are fine, unless your values are accessed somewhere else without synchronization.

By the way, if you did make ar volatile instead of using synchronized methods, you would need to make idx volatile too. But that still would not be sufficient synchronization because two different threads running append at the same time could wreak havoc.

Actually, there's another problem with using a volatile array: changing a value in the array does not trigger a cache synchronization. Only reassigning the array (like you do when creating a bigger array) triggers a cache flush.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文