Философия Java

         

Провалившееся ускорение


Контейнеры Java также имеют механизм, предотвращающий возникновение более одного процесса для изменения содержимого контейнера. Эта проблема возникает, если вы используете итерации контейнера в некоторых других процессах для прохода, вставки, удаления или изменения объектов контейнера. Возможно, вы уже прошли тот объект, возможно, он перед вами, возможно размер контейнера сократился после того, как вы вызвали size( ) — есть много способов для бедствия. Библиотека контейнеров Java разработала механизм провала ускорения, который следит за изменениями контейнера, происходящие в более чем одном процессе. Если определяется, что кто-то еще изменяет контейнер, немедленно возникает ConcurrentModificationException. Это аспект “провала ускорения”, означающий, что не нужно пробовать определять проблему или использовать более сложный алгоритм.

Достаточно просто увидеть работу механизма провала ускорения — все, что вам нужно сделать, это создать итератор, а затем добавить кое-что к коллекции, на которую указывает итератор, как в этом примере:

//: c09:FailFast.java

// Демонстрация поведения "проваливания ускорения".

import java.util.*;

public class FailFast { public static void main(String[] args) { Collection c = new ArrayList(); Iterator it = c.iterator(); c.add("An object"); // Причина исключения:

String s = (String)it.next(); } } ///:~

Исключение возникает из-за того, что что-то помещается в контейнер после того, как итератор запрошен из контейнера. Возможность того, что две части программы могут модифицировать один и тот же контейнер, производит нежелательное состояние, так что исключение предупреждает вас, что вы должны изменить ваш код — в этом случае, запрашивайте итератор после того, как добавите все элементы в контейнер.

Обратите, что вы не можете извлечь пользу из этого рода слежения, когда вы получаете доступ к элементам List, используя get( ).



Содержание раздела