java实例成员损坏

时间:2018-05-22 11:24:23

标签: java corrupt-data

我有一个Java 1.6多线程应用程序(5-7个线程,大多数空闲),这有一个奇怪的行为 该流程涉及使用4字节ID更新设备 我将ID保存在专用字节数组中。当更新成功时,在大约4秒后,设备发送一条STATUS消息,在该消息中我将其ID与我持有的ID进行比较,并清除私有咬合阵列并禁用错误定时器。
所有工作都在单例类实例中完成。

奇怪的行为:
我从一个定期调用的方法打印私有字节数组的值。 在等待STATUS消息的4秒内,日志显示不同的ID(不是垃圾,而是另一个对象的4字节ID)。使用断点检查值会显示此无效值(这意味着它不是日志错误) 但是,当STATUS消息到达时,我将ID与我持有的ID进行比较,它们匹配!

我将私有成员移动到同步的getter / setter中,添加了更改的日志,但没有发现问题。

这是我的setter / getter的伪代码和周期状态+令人不安的日志:

public class Manager {
    private volatile byte[] readerID = null;

    public synchronized void setReaderID(byte[] readerID) {
        this.readerID = readerID;
        logger.debug("readerID = {}", StringUtilities.binaryToAscii(this.readerID));
    }

    public synchronized byte[] getReaderID() {
        if (this.readerID == null)
            return null;
        return Arrays.copyOf(this.readerID, this.readerID.length);
    }

    /* Called every second */
    public void periodicStatus() {
        logger.debug("readerID = {}", StringUtilities.binaryToAscii(getReaderID()));
    }
}

13:53:46,103|ad-5|INFO |Manager|readerUpdateFinish(): Received firmware install finish for reader 000189D0 at slot 0
13:53:46,103|ad-5|DEBUG|Manager|setReaderID(): readerID = 000189D0
13:53:46,103|ad-5|DEBUG|Manager|readerUpdateFinish(): triggered reader firmware timer, 1526986426103, 000189D0
13:53:46,408|ad-5|DEBUG|Manager|periodicStatus(): readerID = E69EAD03 // <- where's the setter???
13:53:50,030|ad-5|INFO |Manager|readerStatus(): Received status information for reader 000189D0 at slot 0
13:53:50,031|ad-5|DEBUG|Manager|setReaderID(): readerID = null
13:53:50,031|ad-5|DEBUG|Manager|readerStatus(): timer cleared, null

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

正如Progman指出的那样,readerID通过引用传递。它从传输层到达,作为实例成员保存在那里,并通过以下传入消息进行更新,并显示正在显示的新ID。