повреждение экземпляра Java - PullRequest
0 голосов
/ 22 мая 2018

У меня есть многопоточное приложение Java 1.6 (5-7 потоков, большинство бездействует), которое ведет себя странно.
Поток включает обновление устройства с 4-байтовым идентификатором.
Я держуидентификатор в приватном байтовом массиве.Когда обновление завершается успешно, через ~ 4 секунды устройство отправляет сообщение STATUS, в котором я сравниваю его идентификатор с тем, который я держу, очищаю частный массив bite и отключаю таймер ошибок.
Всеработа выполняется в экземпляре класса Singleton.

Странное поведение:
Я печатаю значение частного байтового массива из метода, который вызывается периодически.В течение 4 секунд ожидания сообщения STATUS в журнале отображается другой идентификатор (не мусор, а 4-байтовый идентификатор другого объекта).Проверка значения с помощью точки останова показывает это недопустимое значение (то есть это не ошибка журнала).
Но, тем не менее, когда приходит сообщение STATUS, я сравниваю идентификатор с тем, который у меня будет, и они совпадают!

Я переместил приватный член в синхронизированный метод получения / установки, добавив журнал изменений, который не улавливает проблему.

Вот псевдокод моего установщика / получателя и периодическое состояние+ тревожный журнал:

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 голосов
/ 27 мая 2018

Как указал Progman, readerID передается по ссылке.Он поступает с транспортного уровня, хранится там как член экземпляра и обновляется следующим входящим сообщением с новым идентификатором, который отображается.

...