У меня возникло странное поведение с использованием ArrayBlockingQueue, который я использую для связи между определенными шагами в приложении Java.Странное поведение arrayBlockingQueue с элементами массива
Я использую 1 статический ArrayBlockingQueue, как инициализируется так:
protected static BlockingQueue<long[]> commandQueue;
Вслед за конструктором, который имеет это как один из его линий:
commandQueue = new ArrayBlockingQueue<long[]>(amountOfThreads*4);
Где amountOfThreads
дается в качестве аргумента конструктора ,
Я тогда производитель, который создает массив long[2]
дает ему некоторые значения, а затем предлагает его в очередь, то я изменить одно из значений массива непосредственно после него и предложить его еще раз в очереди:
long[] temp = new long[2];
temp[0] = currentThread().getId();
temp[1] = gyrAddress;//Address of an i2c sensor
CommunicationThread.commandQueue.offer(temp);//CommunicationThread is where the commandqueue is located
temp[1] = axlAddress;//Change the address to a different sensor
CommunicationThread.commandQueue.offer(temp);
Потребитель затем берет эти данные и открывает подключение i2c к определенному датчику, получает некоторые данные от упомянутого датчика и передает данные обратно с использованием другой очереди. На данный момент я установил, что потребитель просто потребляет голову и печатает данные.
long[] command = commandQueue.take();//This will hold the program until there is at least 1 command in the queue
if (command.length!=2){
throw new ArrayIndexOutOfBoundsException("The command given is of incorrect format");
}else{
System.out.println("The thread with thread id " + command[0] + " has given the command to get data from address " +Long.toHexString(command[1]));
}
Теперь для тестирования у меня есть продюсер нить с этими адресами (byte) 0x34, (byte)0x44
Если все идет правильно, мой вывод должен быть:
The thread with thread id 14 has given the command to get data from address 44
The thread with thread id 14 has given the command to get data from address 34
Однако я получаю:
The thread with thread id 14 has given the command to get data from address 34
The thread with thread id 14 has given the command to get data from address 34
Какой бы означает, что он отправляет массив temp после его изменения.
Вещи, которые я сделал, чтобы исправить: Я пробовал спать, если бы я добавил 150 мс сна, тогда ответ правильный. Однако этот метод совершенно очевидно влияет на производительность ... Поскольку метод возвращает предложение истинный Я попробовал следующий фрагмент кода
boolean tempBool = false;
while(!tempBool){
tempBool = CommunicationThread.commandQueue.offer(temp);
System.out.println(tempBool);
}
, которая печатает правду. Это не повлияло.
Я пытался печати temp[1]
после этого в то время как петли и в этот момент он является правильное значение. (Он печатает 44
однако потребитель получает 34
)
Что, скорее всего, это дело является проблемой syncronisation, однако я подумал, что целью объекта BlockingQueue было бы решение этого.
Любая помощь или предложение относительно работы этого BlockingQueue были бы весьма полезны.Позвольте мне напомнить о том, что это мой первый опыт работы с очередями между потоками в java и окончательная программа будет работать на малине pi, используя библиотеку pi4j для связи с датчиками.
Я с подозрением, что у вас есть статические переменные, которая инициализируется в конструктор. Статические переменные не принадлежат экземпляру, поэтому они не должны инициализироваться при построении экземпляра; значение будет перезаписано при следующем создании экземпляра. –
Вы изменяете массивы, которые совместно используются потоками без какой-либо синхронизации. Не. И что еще хуже, вы, кажется, всегда сохраняете один и тот же массив в очереди. Это не может работать. Вместо использования массивов из 2 длин, создайте ** неизменный ** класс, содержащий два длинных поля, и сохраните их в очереди. Или, по крайней мере, не изменяйте массив, как только он находится в очереди. –
@AndyTurner Я делаю это, так как мне нужно установить размер в зависимости от количества потоков, я создаю только один экземпляр из этого класса, поэтому это не имеет большого значения. – Ylva