Java提供subList
函数来获取指定索引之间的列表视图,并由父列表支持,这意味着对subList
所做的任何更改都将反映在实际列表中。我想知道的是,如果线程试图访问它们,这些子列表是否会被父列表锁定。
作为一个例子,如果我有一个ArrayList
的100个元素,并且我创建了4个子列表,每个子列表有25个元素,4个线程尝试在这些子列表上并行工作,它们是否可以在它们的独立子列表中工作真正的并行方式还是第一个被执行的线程,锁定后备arraylist?
如果默认情况下没有锁定arraylist,我假设线程将在子列表上并行运行而不等待彼此,如果我以编程方式确保或者更确切地说逻辑本身确保这些线程永远不会在除了他们的子列表然后它将真正平行处理子列表,对吗?
executor.addTask(new Thread(doneSignal, parentList.subList(subListStart, subListEnd)));
我问的原因是,我试图并行循环遍历子列表,并注意到它比不创建4个线程并在实际父列表上循环要慢得多。
答案 0 :(得分:1)
正如Javadoc for java.util.ArrayList
中所述:
请注意,此实施未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。
当然,这适用于subList
方法。因此,ArrayList
本身没有锁定;如果需要,你需要自己动手。
答案 1 :(得分:0)
我想知道的是,如果线程试图访问它们,这些子列表是否会被父列表锁定。
不,他们不会。
... [w]生病他们以真正平行的方式处理他们的独立子列表
是。 (除非有其他因素反对并行性。)
我试图并行循环遍历这些子列表,并注意到它比不创建4个线程并在实际父列表上循环要慢得多。
这可能归结为其他事情。例如,线程创建开销,线程池太小,或者在内核太少时尝试运行多线程代码。
另一种可能性是您正在创建同步列表的子列表。如果这样做,当子列表方法将操作委托给父列表时,这些操作将全部锁定相同的列表。但请注意,是由此负责的父列表,而不是子列表。