如何在Java中以线程安全的方式通过构造函数传递列表?

时间:2011-09-13 19:32:01

标签: java multithreading

我有一个Java程序,它从文件中读取大量字符串列表,每隔几百个字符串创建一个列表,并将每个列表传递给以某种方式处理它们的新线程。这可能包括修改列表。我想知道实现这一点的最佳方法,以便线程不会踩到彼此的列表。请注意,我不关心这个列表实际上是什么类型的数据结构。它可以是数组,列表,队列,堆栈等,顺序无关紧要。

谢谢, 贾里德

4 个答案:

答案 0 :(得分:2)

好的,ImmutableList(来自番石榴)怎么样?如果需要,每个线程可以随后将其复制到自己的线程本地可变列表中。

如果真的必须是可变的,那么CopyOnWriteArrayList也可以。 : - )

答案 1 :(得分:2)

如果每个线程都有自己的列表,数组,队列等,则没有问题。如果使用List.subList(),则必须获取副本,因为这会在原始列表中创建视图(如果在多个线程中对其进行修改,则会导致问题)。

答案 2 :(得分:1)

如果你正在处理可变数据结构(例如你可以在其中添加/删除元素的列表),你真的需要在线程之间共享这些数据结构,这些都是我的担忧:

  • 至少应该同步对数据结构的所有访问权限。最好将数据包装在一个类中,添加一些

    final Object lock = new Object();
    

    并围绕所有相关操作执行synchronized (lock) { ... }。像

    这样的循环
    while (!isEmpty())
        remove(0);
    

    将是一个典型的例子,需要包含在synchronized块中。

  • 然后,您需要确保共享数据结构也是“逻辑同步”的。如果一个线程例如“添加一个临时对象”而其他方法无法看到,则需要在这段时间内锁定(获得专有权)数据结构。即只是在synchronized块中包装添加和删除操作可能还不够。

  • 如果可能,请使用java.util.concurrent package中提供的数据结构。这些事情真的很棘手,你可以通过利用这个包中已经调试的数据结构来节省一两个头痛。

    该软件包中的示例类包括CopyOnWriteArrayListConcurrentSkipListSet

答案 3 :(得分:1)

我从您的问题中了解到,您正在对大数据进行分区并在新线程中使用每个分区。

如果这是正确的,我没有看到问题,因为线程之间没有共享分区,所以没有踩踏的机会。

对于分区,您只需选择一个限制并从该数据中创建一个列表/数组并使用它。