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, В этом порядке (с возможными другими значениями, вставленными между ними в зависимости от того, что еще сбрасывается).

Другие вопросы по тегам