Я использую шаблон наблюдателя и BlockingQueue, чтобы добавить несколько экземпляров. Теперь в другом методе я использую очередь, но кажется, что take () ждет вечно, хотя я делаю это так:
/** {@inheritDoc} */
@Override
public void diffListener(final EDiff paramDiff, final IStructuralItem paramNewNode,
final IStructuralItem paramOldNode, final DiffDepth paramDepth) {
final Diff diff =
new Diff(paramDiff, paramNewNode.getNodeKey(), paramOldNode.getNodeKey(), paramDepth);
mDiffs.add(diff);
try {
mDiffQueue.put(diff);
} catch (final InterruptedException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
mEntries++;
if (mEntries == AFTER_COUNT_DIFFS) {
try {
mRunner.run(new PopulateDatabase(mDiffDatabase, mDiffs));
} catch (final Exception e) {
LOGWRAPPER.error(e.getMessage(), e);
}
mEntries = 0;
mDiffs = new LinkedList<>();
}
}
/** {@inheritDoc} */
@Override
public void diffDone() {
try {
mRunner.run(new PopulateDatabase(mDiffDatabase, mDiffs));
} catch (final Exception e) {
LOGWRAPPER.error(e.getMessage(), e);
}
mDone = true;
}
тогда как mDiffQueue является LinkedBlockingQueue, и я использую его так:
while (!(mDiffQueue.isEmpty() && mDone) || mDiffQueue.take().getDiff() == EDiff.INSERTED) {}
Но я думаю, что первое выражение проверено, тогда как mDone неверно, тогда, возможно, mDone установлено в true (наблюдатель всегда многопоточный?), Но он уже вызывает mDiffQueue.take ()? : - /
Редактировать: Я действительно не понимаю сейчас. Я недавно изменил это на:
synchronized (mDiffQueue) {
while (!(mDiffQueue.isEmpty() && mDone)) {
if (mDiffQueue.take().getDiff() != EDiff.INSERTED) {
break;
}
}
}
Если я немного подожду в отладчике, он будет работать, но он также должен работать в «реальном времени», поскольку mDone инициализируется как false, и, следовательно, условие while должно быть истинным, а тело должно выполняться.
Если mDiffQueue пусто, а mDone равно true, оно должно пропустить тело цикла while (что означает, что очередь больше не заполняется).
Редактировать: Кажется, это:
synchronized (mDiffQueue) {
while (!(mDiffQueue.isEmpty() && mDone)) {
if (mDiffQueue.peek() != null) {
if (mDiffQueue.take().getDiff() != EDiff.INSERTED) {
break;
}
}
}
}
Хотя я не понимаю, почему функция peek () обязательна.
Edit:
То, что я делаю, это итерация по дереву, и я хочу пропустить все INSERTED узлы:
for (final AbsAxis axis = new DescendantAxis(paramRtx, true); axis.hasNext(); axis.next()) {
skipInserts();
final IStructuralItem node = paramRtx.getStructuralNode();
if (node.hasFirstChild()) {
depth++;
skipInserts();
...
По сути, вычисление максимальной глубины или уровня в дереве без учета узлов, которые были удалены в другой ревизии дерева (для сравнения Sunburst-визуализации), но все в порядке, это, возможно, выходит за рамки. Просто чтобы проиллюстрировать, что я делаю что-то с узлами, которые не были вставлены, даже если это просто настройка максимальной глубины.
С уважением,
Johannes