gpt4 book ai didi

java - java.util.concurrent 中的内存一致性

转载 作者:太空宇宙 更新时间:2023-11-04 08:40:37 25 4
gpt4 key购买 nike

来自Memory Consistancy Property , 我们知道:“将对象放入任何并发集合之前的线程中的操作发生在另一个线程中从集合中访问或删除该元素之后的操作。”

这是否意味着:如果我在一个线程中创建一个对象并将其放入 ConcurrentLinkedQueue 中,另一个线程将看到该对象的所有属性,而无需对该对象进行其他同步?

例如:

public class Complex{

int index;

String name;

public Complex(int index, String name){

this.index = index;

this.name = name;

}

public String getName(){

return name;

}

public int getIndex(){

return index;

}

}

public class SharedQueue{

public static ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

}

在一个线程中:

……

Complex complex = new Complex(12, "Sam");

SharedQueue.queue.add(complex);

……

在另一个线程中

......

Complex complex = SharedQueue.queue.poll();

System.out.printly(complex.getIndex() + ";" + complex.getName());

............

第二个线程一定会看到complex对象的属性吗?如果在第一个线程将对象放入队列后,第二个线程恰好获取该对象并打印它。

我们知道,在正常情况下,如果是共享的,我们应该在多线程环境中同步对象。

喜欢

public class Complex{

int index;

String name;

public Complex(int index, String name){

this.index = index;

this.name = name;

}

public synchronized String getName(){

return name;

}

public synchronized int getIndex(){

return index;

}

}

最佳答案

  1. 所有线程都会看到它们可以获得引用的所有对象,所以是的,这也适用于集合。并发集合使用同步来避免两个或多个线程同时访问它们时中断(例如,for 循环可能中断),因此您可以使用它们在线程之间共享对象。

  2. 如果您的对象是不可变的,即只读,如上面的 Complex 类(添加最终修饰符),那么您不需要同步对其的访问,因为它是线程安全的。

同步的目的是确保变量在 n 次操作中保持一致。示例:

如果你想计算

i = i + 2;

那么这包括首先读取 i 的值,加 2,然后将该值设置回 i。

现在,如果在您添加 2 之后某个其他线程出现并更新 i,那么您实际上会覆盖此更新,因为您仍然保留基于先前值 + 2 的总和,并将其设置回 i。

关于java - java.util.concurrent 中的内存一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5407254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com