2015-07-21 4 views
2

Почему перегруженный метод writeObject в LinkedList не проверяет на ConcurrentModificationException, где это делает ArrayList.
Я видел Java код LinkedListПочему метод writeObject в LinkedList не проверяет на ConcurrentModificationException

private void writeObject(java.io.ObjectOutputStream s) 
     throws java.io.IOException { 
     // Write out any hidden serialization magic 
     s.defaultWriteObject(); 

     // Write out size 
     s.writeInt(size); 

     // Write out all elements in the proper order. 
     for (Node<E> x = first; x != null; x = x.next) 
      s.writeObject(x.item); 
    } 

и Явы код ArrayList

private void writeObject(java.io.ObjectOutputStream s) 
     throws java.io.IOException{ 
     // Write out element count, and any hidden stuff 
     int expectedModCount = modCount; 
     s.defaultWriteObject(); 

     // Write out size as capacity for behavioural compatibility with clone() 
     s.writeInt(size); 

     // Write out all elements in the proper order. 
     for (int i=0; i<size; i++) { 
      s.writeObject(elementData[i]); 
     } 

     if (modCount != expectedModCount) { 
      throw new ConcurrentModificationException(); 
     } 
    } 

Что может быть возможные причины.

ответ

1

Первое наблюдение: javadocs для ArrayList и LinkedList не говорят, что при выполнении сериализации выполняются параллельные проверки модификации. Поэтому для выполнения проверок согласуется с соответствующими контрактами API или нет.

Почему они могут быть разными?

Не изучая историю исходного кода Java вплоть до Java 1.1, мы можем только догадываться. Возможно, это был надзор или раннее исправление ошибок, которое было сделано в одном классе, а другое. Возможно также, что несогласованность была замечена, но она не была исправлена ​​из-за опасений, что исправление нарушит код клиента.

Я не мог найти связанных отчетов об ошибках в базе данных ошибок Java.

+0

Спасибо и Стивен, у меня есть два вопроса 1. Если это ошибка и пока не сообщается, как мы можем сообщить об этом, и 2. «Исправить будет разрыв кода клиента», как он сломается? потому что если мы не справимся, это вызовет некоторые проблемы, такие как Маленький Санти. – Pydi

+0

1. Это не ошибка. 2. Кого-то код может зависеть от одновременных изменений, в то время как связанный список сериализуется, не вызывая исключения. –

0

Я думаю, что одна причина может заключаться в том, что в LinkList вызывается IndexOutOfBoundException во время записи (вы не можете одновременно писать на нем) Я не уверен и должен проверить это.

+0

Спасибо Amit, но как он может вызывать IndexOutOfBoundException, потому что он не работает по индексу, он работает на следующем адресе. – Pydi

+0

Правильно, но метод ввода LinkedList выбрасывает это, вы в основном вставляете объект в какое-то место индекса в LinkedList (add, addAll etc метод ввода вызова, который генерирует IndexOutOfBoundException) –

1

После анализа кода, я предполагаю, что это явно ошибка в LinkedList:

Обратите внимание, что первое, что он делает это сочинительство на потоке размера из списка, а затем его узлы. Но, если какой-либо узел добавляется/удаляется при сериализации списка, значение уже написанного не является когерентным больше с количеством узлов, фактически сериализованных.

Клиент, который сериализует LinkedList бы в конечном итоге с ObjectStream, объявляющего 5 элементов, но имеет только 4. (И это в конечном счете производить исключение в readObject.)

+0

Спасибо Маленький Санти, это точно мой вопрос: что происходит, когда добавляется/удалено во время сериализации. Так это была ошибка? – Pydi

+0

Если, согласно моим рассуждениям, алгоритм 'LinkedList.writeObject' может создавать некогерентную и фиктивную информацию в потоке сериализации, я должен заключить: Да, это ошибка _is_. –

Смежные вопросы