Java 数组:同步 +原子*或同步就足够了?

发布于 2024-12-18 18:03:50 字数 1216 浏览 3 评论 0原文

这个问题被问了一遍又一遍,但我仍然有一个疑问。当人们说同步创建了内存屏障时,这个内存屏障适用于什么,任何缓存变量?这看起来不太可行。

因此,由于这个疑问,我编写了一些如下所示的代码:

final AtomicReferenceArray<Double> total=new AtomicReferenceArray<Double>(func.outDim);
for(int i=0; i<func.outDim; i++) total.set(i, 0.);
for(int i=0; i<threads; i++){
    workers[i]=new Thread(new Runnable(){
        public void run() {
            double[] myPartialSum=new double(func.outDim);
            //some lengthy math which fills myPartialSum...

            //The Atomic* guarantees that I'm not writing local copies of the Double references (whose value are immutables, so it's like an array of truly volatile doubles) in variable total, synchronized(total) atomizes the sum
            synchronized(total){ for(int i=0; i<func.outDim; i++) total.set(i, total.get(i)+myPartialSum[i]); }
        };
    workers[i].start();
}
//wait for workers to terminate...

//print results accessing total outside of a synchronized(total) block, since no worker is alive at this point.

我想知道是否可以用普通的 double[] 替换 Total 类型:这将需要同步(total)(在 run() 中)方法)确保我不会使用双精度数组中每个索引的本地副本,也就是说,内存栅栏不仅仅适用于 total 本身的值(位于幕后)一个指针),但是指向总计也是如此。会发生这种情况吗?

This question has been asked again and again, but I have still a doubt. When people say that synchronized creates a memory barrier, what does this memory barrier apply to, ANY cached variable? This doesn't look like feasible.

So, due to this doubt, I have written some code that looks like this:

final AtomicReferenceArray<Double> total=new AtomicReferenceArray<Double>(func.outDim);
for(int i=0; i<func.outDim; i++) total.set(i, 0.);
for(int i=0; i<threads; i++){
    workers[i]=new Thread(new Runnable(){
        public void run() {
            double[] myPartialSum=new double(func.outDim);
            //some lengthy math which fills myPartialSum...

            //The Atomic* guarantees that I'm not writing local copies of the Double references (whose value are immutables, so it's like an array of truly volatile doubles) in variable total, synchronized(total) atomizes the sum
            synchronized(total){ for(int i=0; i<func.outDim; i++) total.set(i, total.get(i)+myPartialSum[i]); }
        };
    workers[i].start();
}
//wait for workers to terminate...

//print results accessing total outside of a synchronized(total) block, since no worker is alive at this point.

I wonder if it's possible to just substitute the type of total with a plain double[]: this would require that synchronized(total) (in the run() method) assures that I'm not working with local copies of each index in the array of doubles, that is, the memory fence does not apply only to the value of total itself (which is under the hood a pointer), but to the indexes of total too. Does this happen?

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

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

发布评论

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

评论(2

仄言 2024-12-25 18:03:50

内存屏障适用于所有内存引用,甚至是不相关的内存引用。当您同步total时,您将看到所有内存值的最新副本,并且当您离开该块时,会出现另一个内存屏障。

The memory barrier applies to all memory references, even unrelated ones. When you synchronize total you will see an up to date copy of any memory values and when you leave the block, there is another memory barrier.

假面具 2024-12-25 18:03:50

如果我的理解是正确的,synchronized(total) 将同步任何total 的访问,因此应该同步对以下值的访问(读取和写入)也是一个数组。

由于 double 数组直接包含值而不是引用,因此在执行同步块期间其他线程不应访问这些值。如果您有一个对象数组,您将无法更改数组中的引用,但您仍然可以访问对象本身。

If my understanding is correct synchronized(total) would synchronize any access to total and thus should synchronize access (read and write) to the values in an array, too.

Since a double array directly contains the values instead of references, those should not be accessible by other threads during execution of the synchronized block. If you had an array of objects you would not be able to change the references in the array but you could still access the objects themselves.

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