Java:大型集合和并发线程

时间:2009-12-18 06:58:05

标签: java concurrency multithreading

我正面临这个问题: 我有很多线程(1024)访问一个大型集合 - 矢量。 题: 是否有可能对它做一些事情,这将允许我对它进行并发操作而不必同步所有事情(因为这需要时间)?我的意思是,就像Mysql数据库一样,你不必担心同步和线程安全问题。在Java中有一些类似的集合吗?感谢

5 个答案:

答案 0 :(得分:7)

Vector是一个非常古老的Java类 - 早于Collections API。它在每次操作时都会同步,所以你不会有任何运气试图加速它。 您应该考虑重新编写代码以使用ConcurrentHashMap或LinkedBlockingQueue,它们针对并发访问进行了高度优化。

如果不这样做,你提到你喜欢与数据库类似的性能和访问语义 - 为什么不使用专用数据库或消息队列?他们可能会比你以前更好地实现它,并且你编写的代码更少!

[编辑]鉴于你的评论:

all what thread does is adding elements to vector 
(only if num of elements in vector = 0) & 
removing elements from vector. (if vector size > 0)

听起来非常像你应该使用的东西更像是队列而不是列表!大小为1的有界队列将为您提供这些语义 - 虽然我会质疑为什么如果已经存在某些内容则无法添加元素。当你有成千上万的线程时,这似乎是一种非常低效的设计。

答案 1 :(得分:5)

首先,这个设计听起来不对。听起来你需要考虑使用适当的数据库而不是简单的数据结构,即使这意味着只使用像HypersonicDB的内存中实例这样的东西。

但是,如果你坚持以这种方式做事,那么java.util.concurrent包有许多高度并发的非锁定数据结构。其中一个可能适合您的目的(例如ConcurrentHashMap,如果您可以使用Map而不是List

答案 2 :(得分:2)

看起来你正在实施生产者消费者模式,你应该谷歌“生产者消费者java”或看看the BlockingQueue interface

答案 3 :(得分:0)

我同意skaffman关于查看java.util.concurrent。

ConcurrentHashMap具有很强的可扩展性。但是,对它的size()调用只返回一个近似值。所以例如你的应用程序偶尔会添加元素,即使!(vector中的元素数量= 0)。

如果您想严格执行您提供的条件,除了同步之外别无他法。

我猜你可以让你的用户在一个队列上发布一个可调用的帖子并且只有一个线程来处理这个突变,而不是有大量的上下文切换。这将消除对集合进行同步的需要。用户线程可以等待Future.get()。

只是一个想法。

答案 4 :(得分:0)

如果您不想更改数据结构并且只进行不频繁的写入,则可能还会使用一个或多个ReentrantReadWriteLock来同步访问。然后许多线程可以同时读取,但是当线程想要写入时,所有读取都会被阻塞,直到写入完成。

但是您应该检查所使用的数据结构是否适合该任务,或者更多java.util或java.util.concurrent类中的另一个是否更合适。顺便说一下,java.util.Vector 同步的。