java.util.ConcurrentLinkedQueue

我想使用java.util.ConcurrentLinkedQueue作为Servlet的非持久队列。 这是来自类的javadoc的模糊。

基于链接节点的无界线程安全队列。 当许multithreading共享对公共集合的访问权限时,ConcurrentLinkedQueue是一个合适的选择。 此队列不允许null元素。

现在假设我在servlet上有1000个并发请求,每个线程都需要将一个对象嵌入到ConcurrentLinkedQueue中。 从描述中,我应该得出结论,处理负载没有问题吗? 我需要的保证是:

  1. 我自动收到线程安全保证,而无需自己进行同步。
  2. 如果流量负载超过1000并发请求,我将不会丢失任何请求。

谢谢

你本质上是在问三个不同的问题(其中两个是明确的,一个是隐含的。)在这里,我的答案如下:

1.如果我使用java.util.ConcurrentLinkedQueue是否需要进行自己的同步?

并发收集的primefaces操作将为您同步。 换句话说,对队列的每个单独调用都是保证线程安全的,无需您执行任何操作。 保证线程安全的是您对集合执行的非primefaces操作。

例如,这是线程安全的,没有您的任何操作:

 queue.add(obj); 

要么

 queue.poll(obj); 

然而; 对队列的非primefaces调用不是自动线程安全的。 例如,以下操作不是自动线程安全的:

 if(!queue.isEmpty()) { queue.poll(obj); } 

最后一个不是线程安全的,因为很可能在调用时间isEmpty和调用时间轮询之间,其他线程将在队列中添加或删除项目。 执行此操作的线程安全方式如下:

 synchronized(queue) { if(!queue.isEmpty()) { queue.poll(obj); } } 

同样……对队列的primefaces调用是自动线程安全的。 非primefaces调用不是。

2.如果有1000个并发请求,我保证不会丢失对java.util.ConcurrentLinkedQueue调用吗?

因为这是一个无限制的实现,所以无论同时发出多少请求都可以保证,队列不会丢失这些请求(因为队列的并发性……你可能会耗尽内存或某些内容……但是队列实现本身不会成为您的限制因素。)在Web应用程序中,还有其他机会“丢失”请求,但队列的同步(或缺少)将不是您的原因。

3. java.util.ConcurrentLinkedQueue表现得足够好吗?

通常,当我们谈论并发时,我们会讨论“正确性”。 我的意思是,Concurrent类保证它们是线程安全的(或者可以防止死锁,饥饿等)。当我们谈论这个时,我们不会对性能做出任何保证(对集合的调用速度有多快)是) – 我们只保证他们“正确”。

然而; ConcurrentLinkedQueue是一个“无需等待”的实现,所以这可能是你能得到的高效。 保证servlet的加载性能(包括使用并发类)的唯一方法是在负载下测试它。

请记住,对于单个成员的调用,队列只是线程安全的。 不要编写这样的代码并期望它能够工作:

 if (queue.Count!=0) queue.Dequeue().DoSomething(); 

在这两个操作之间,另一个线程可能已使最后一个元素出列。 我并不熟悉Java集合,但我认为在这种情况下Dequeue会返回null ,给你一个例外。

  1. 由于队列是线程安全的,因此您无需执行任何同步即可确保线程安全。 但是,您应确保所有线程都具有对队列的相同访问权限,以避免饥饿,忙等待等…

  2. 由于队列是无限制的,因此队列的大小仅受可用内存量的限制。

是的,对于你的两个问题。

并发队列线程安全的(由于下面使用了无块算法,因此是高效的)。 线程安全 意味着并发访问的数量必须没有任何区别(我还没有听说过竞争条件,保证不会在xyz并发访问之下发生)。

除此之外 – multithreading应用程序中的最佳性能比这更复杂。 但使用真正的并发收集并​​不是一个糟糕的开端。