我有一个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
有什么想法吗?
答案 0 :(得分:0)
正如Progman指出的那样,readerID通过引用传递。它从传输层到达,作为实例成员保存在那里,并通过以下传入消息进行更新,并显示正在显示的新ID。