gpt4 book ai didi

java - 私有(private)变量在对象之间共享

转载 作者:行者123 更新时间:2023-12-01 21:14:30 26 4
gpt4 key购买 nike

我的类(class)看起来像

public class Sender {
private LoggingAdapter log = Logging.getLogger(this.toString());
private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();

public void send(final CSAMessage message) {
doSend(message);
sentHistory.add(message);
}

private void doSend(CSAMessage message) {
//do send stuff
}
}

问题是 - 当同时调用 Sender 类的两个实例时,它们共享私有(private)的 sentHistory 字段。在日志中它看起来像

Sender1 send(...) was called, message was added to own sendHistory list
Sender2 send(...) was called, message was added to Sender1 sendHistory list

这怎么可能?我确信 Sender1 和 Sender2 是不同的实例,它们从不同的线程调用,但调用是在同一时间进行的。

我已经尝试使变量“ volatile ” - 没有结果
该 block 也没有给出任何结果

private final ArrayList<CSAMessage> sentHistory;

{
sentHistory = new ArrayList<>();
}

仅通过类同步有帮助

public void send(final CSAMessage message) {
synchronized (Sender.class) {
doSend(message);
sentHistory.add(message);
}
}

但这将成为性能瓶颈 - 许多发送者必须能够同时工作。我为什么要这样做?不同的实例必须使用自己的变量!
还有一些以相同方式声明的日志变量,但日志变量不在对象之间共享,每个发送者都从自己的名称写入日志。

最佳答案

标记变量final并按照您的方式初始化它

private final ArrayList<CSAMessage> sentHistory = new ArrayList<>();
// ^^^^^ ^^^^^^^^^^^^^^^^^^^

使得多个实例绝对不可能共享同一个ArrayList

但是,仍然可能的是多个 ArrayList 共享相同的 CSAMessage 实例。如果共享的 CSAMessage 是可变的,则可能会造成共享的错觉。例如,如果 CSAMessage 有一个返回 Sender 的链接,该链接被设置为 send 调用的一部分,则同时进行更改可能会显示该消息就好像它是通过错误的发件人发送的。

关于java - 私有(private)变量在对象之间共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40506495/

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