ArrayList, проверка размера на 2 потока
У меня есть список:
ArrayList list = new ArrayList<> ();
В первом потоке я добавляю элементы (это быстро - 30 в секунду) Во втором потоке я читаю его размер и печатаю в файл.
Первая тема:
synchronized(list){
list.add(PlayerPosition);
}
Второй поток:
synchronized(list){
if(list.size()>0)
out.print(list.size() + " ");
}
Это вывод файла, только часть: 1 1 1 3 3 5 4 6 7 7 9 11 8 9 12 10 14 16
Это неправильно, потому что оно должно только увеличиваться. Может быть 1 1 1, но не может быть 11 8.
У меня большая программа, НО это только случаи из этого списка (я удалил половину кода для его отладки). Нет list.remove()
и т.д. во всем приложении.
У меня есть вопрос: это возможно, что он действует так? Причина иначе - это моя вина где-то в коде.
И да, я пытался с CopyOnWriteArrayList - то же самое. Спасибо!
2 ответа
Возможно, что print
не выполняются в том порядке, в котором вы ожидаете. Измените код второго потока на следующий:
synchronized(list){
if (list.size() > 0) {
synchronized (out) {
out.print(list.size() + " ");
out.flush();
}
}
}
Ваш OutputStream
записывает символы в терминал (или файл, или что-то еще). Без синхронизации по out
и промывка, когда поток 2 говорит OutputStream
Возможно, предыдущая печать еще не закончена. Синхронизация и очистка заставляют поток 2 ждать, пока все символы фактически не будут записаны в терминал, прежде чем продолжить.
Вы можете улучшить код выше несколькими способами. Во-первых, вам не нужно реализовывать примитивы синхронизации самостоятельно. Java уже имеет встроенный SynchronizedList. Collections.synchronizedList(list)
, Это должно все, чтобы вы удалили список баз синхронизирующих блоков.
Для печати другой ответ правильный, нет гарантии, что запись файла между потоками будет происходить последовательно. Например, поток 1 может написать 8
в поток печати, затем поток 2 пишет 11
, Если поток 2 сбрасывается, то поток 1 сбрасывается, результирующий файл будет содержать 11
...8
, В этом порядке (с возможными другими значениями, вставленными между ними в зависимости от того, что еще сбрасывается).