增加 foreach 循环时,Java 似乎挂起。我找不到任何有类似问题的人,所以也许我只是做错了什么,但我无法想象它是什么。我正在从 Neo4J 数据库中提取一组节点,然后对其进行迭代。我没有在循环期间修改那组节点,但过了一会儿,它挂起。这是执行此操作的代码:
IndexHits<Node> usrs = users.get("Type", "User");
System.out.println("Operating on "+usrs.size()+" Users:");
for (Node u : usrs) {
System.out.print(".");
if (inUserBlacklist(u))
continue;
System.out.println("HA");
}
inUserBlacklist(u) 所做的只是根据预设的一组节点检查节点 u,以查看该节点是否属于黑名单的一部分。它不会改变关于节点 u 的任何内容。
Users 是一个 Neo4J 索引,因此对其调用 get() 应该返回一个可迭代的 IndexHits 对象。这个 foreach 循环运行了 269,938 次 foreach 循环。在该迭代结束时,它会打印“HA”,但它不会再打印另一个“.”。它只是挂在那个点,就在迭代 269,939 之前。这使它成为 foreach 循环的阻塞。总共应该有 270,012 次迭代。
我注意到我的黑名单包含 74 个项目,所有这些项目都应在通过此循环时匹配一次。270,012 - 74 = 269,938,但这并不能解释为什么它会阻塞。我所能想到的是,当我调用 continue 时,foreach 循环正在增加迭代器上的位置而不增加其计数器。然后它到了集合的末尾,没有更多的东西,但计数器认为它只有 270,012 中的 269,938。
你们中有人知道为什么 foreach 循环会这样吗?
编辑:堆栈跟踪显示该进程确实卡在 for 循环中(第 116 行):
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.FileDispatcher.pread0(Native Method)
at sun.nio.ch.FileDispatcher.pread(FileDispatcher.java:49)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:248)
at sun.nio.ch.IOUtil.read(IOUtil.java:224)
at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:663)
at org.neo4j.kernel.impl.nioneo.store.PersistenceRow.readPosition(PersistenceRow.java:91)
at org.neo4j.kernel.impl.nioneo.store.PersistenceWindowPool.acquire(PersistenceWindowPool.java:177)
at org.neo4j.kernel.impl.nioneo.store.CommonAbstractStore.acquireWindow(CommonAbstractStore.java:559)
at org.neo4j.kernel.impl.nioneo.store.RelationshipStore.getChainRecord(RelationshipStore.java:349)
at org.neo4j.kernel.impl.nioneo.xa.ReadTransaction.getMoreRelationships(ReadTransaction.java:121)
at org.neo4j.kernel.impl.nioneo.xa.ReadTransaction.getMoreRelationships(ReadTransaction.java:104)
at org.neo4j.kernel.impl.persistence.PersistenceManager.getMoreRelationships(PersistenceManager.java:108)
at org.neo4j.kernel.impl.core.NodeManager.getMoreRelationships(NodeManager.java:666)
at org.neo4j.kernel.impl.core.NodeImpl.getMoreRelationships(NodeImpl.java:427)
- locked <0x77c9b4a0> (a org.neo4j.kernel.impl.core.NodeImpl)
at org.neo4j.kernel.impl.core.IntArrayIterator.fetchNextOrNull(IntArrayIterator.java:91)
at org.neo4j.kernel.impl.core.IntArrayIterator.fetchNextOrNull(IntArrayIterator.java:36)
at org.neo4j.helpers.collection.PrefetchingIterator.hasNext(PrefetchingIterator.java:55)
at org.neo4j.kernel.impl.traversal.TraversalBranchImpl.next(TraversalBranchImpl.java:128)
at org.neo4j.kernel.PreorderBreadthFirstSelector.next(PreorderBreadthFirstSelector.java:48)
at org.neo4j.kernel.impl.traversal.TraverserImpl$TraverserIterator.fetchNextOrNull(TraverserImpl.java:127)
at org.neo4j.kernel.impl.traversal.TraverserImpl$TraverserIterator.fetchNextOrNull(TraverserImpl.java:94)
at org.neo4j.helpers.collection.PrefetchingIterator.hasNext(PrefetchingIterator.java:55)
at org.neo4j.helpers.collection.IteratorWrapper.hasNext(IteratorWrapper.java:42)
at NodePlacement.LoadFromNode(NodePlacement.java:116)
所以......看起来线程仍在运行并且没有被任何东西阻塞。然而它并没有脱离这部分代码。也许关于我的数据库设置的某些东西使它陷入了无限循环?