for (FastList.Node<Concert> n = head(), end = tail(); (n = n.getNext()) != end;) {
Concert concert = n.getValue();
Colored with dumpz.org
В shared() режиме это замечательно. Кажеться, вы экономите на итераторах?
Недавно обнаружилась одна интересная особенность этих хранилищ, по сравнению с чем Concurrent классы из java.util.concurrent версии 1.6 выглядят куда более привлекательными. Как известно, javolution активно пытается переиспользовать удаляемые ноды. Для этого оно помещает их в конец списка за tail (в хэшах аналогично) и соответственно прибивает старые указатели. Поэтому если вы работаете с FastList, FastMap или еще c чем в 2-ух тредах - один читает, другой удаляет, - ваш читающий поток редко будет дочитывать до конца. В основном он будет терять позицию, из-за того что нода на которой он висит, была удалено параллельно пишушим потоком. А если вы не проверяете node.getValue на null будет еще и падать с NullPointerException. Вот рабочий пример (забавно, тут даже нет никаких локов в рутово треде):
final FastList<Integer> list = new FastList<Integer>();
for (int i = 0; i < 104; i++)
list.add(i);
int count = 0;
for (FastList.Node<Integer> n = list.head(), end = list.tail(); (n = n.getNext()) != end;) {
int x = n.getValue();
if (count > 100) {
final FastList.Node<Integer> z = n;
Runnable remover = new Runnable() {
@Override
public void run() {
list.remove(z.getValue());
}
};
Thread removerThread = new Thread(remover);
removerThread.start();
while (removerThread.getState() != Thread.State.TERMINATED) try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
count ++;
}
Colored with dumpz.org
Соответственно, с ConcurrentLinkedQueue такого не происходит. Вы почти спокойно добегаете по списку по ново\старой версии. В частности, если вы начали читать итератор, и другой тред удалил все последующие элементы, вы их все равно увидите. И в большинстве случаев такое поведение оправдано.
Комментариев нет:
Отправить комментарий