2009-12-18 54 views
2

我面临这个问题: 我有很多线程(1024)谁访问一个大集合 - 矢量。 问题: 是否可以做一些有关它的事情,使我可以对其执行并发操作而无需同步所有内容(因为这需要时间)?我的意思是,像Mysql数据库的作品,你不必担心同步和线程安全问题。在Java中有一些集合吗?谢谢Java:大集合和并发线程

+1

为什么你有1024线程?太疯狂了。 –

+0

我有8个核心CPU和8GB内存,有3000个用户访问我的应用程序,所以我认为没关系,不是吗? – Andrey

+0

@Mark:不一定,它只是一个非常高度的并发性。但是,8个内核上的1024个线程可能过多。 – skaffman

回答

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的有界队列会给你这些语义 - 尽管我会问,为什么你不能添加元素,如果已经有东西。当你有成千上万的线程时,这似乎是一个非常低效的设计。

5

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

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

+0

-1:考虑到他对Vector的使用的评论,我认为Steven Schlansker关于考虑队列的答案更合适。 –

+1

如果你认为这是一个糟糕的问题,你会低估一个答案,而不是因为你认为另一个答案更好。 – skaffman

0

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

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

如果你想严格执行你给出的条件,除了同步外没有别的办法。

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

只是一个想法。

0

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

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