我想将java.util.ConcurrentLinkedQueue用作Servlet的非持久队列。
这是该类的javadoc的内容。



现在想象一下我在servlet上有1000个并发请求,并且每个线程都需要将一个对象放入ConcurrentLinkedQueue中。从描述中,我是否应该得出结论,处理负载不会有问题?我将需要的保证是:

  • 我不需要执行自己的同步就自动收到线程安全保证。
  • 如果流量负载超过1000个并发请求,我将不会丢失任何请求。

  • 谢谢

    最佳答案

    您实质上是在问三个不同的问题(其中两个明确地和一个隐式地。)这是我的答案:

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

    并发集合上的原子操作将为您同步。换句话说,确保对队列的每个单独调用都是线程安全的,无需您执行任何操作。什么是而不是保证线程安全的是您在集合上执行的所有非原子操作。

    例如,这是线程安全的,无需您执行任何操作:

    queue.add(obj);
    

    要么
    queue.poll(obj);
    

    然而;对队列的非原子调用不是自动线程安全的。例如,以下操作是而不是自动线程安全:
    if(!queue.isEmpty()) {
       queue.poll(obj);
    }
    

    最后一个线程不是线程安全的,因为很有可能在调用isEmpty和调用时间轮询之间,其他线程将在队列中添加或删除项目。执行此操作的线程安全方式如下所示:
    synchronized(queue) {
        if(!queue.isEmpty()) {
           queue.poll(obj);
        }
    }
    

    再次...对队列的原子调用自动是线程安全的。非原子调用不是。

    2.如果同时有1000个请求,我是否保证不会丢失对java.util.ConcurrentLinkedQueue的 call ?

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

    3. java.util.ConcurrentLinkedQueue的性能是否足够好?

    通常,我们在谈论并发时谈论“正确性”。我的意思是说,并发类保证它们是线程安全的(或对死锁,饥饿等具有鲁棒性)。当我们谈论这一点时,我们并没有对性能做任何保证(对集合的调用有多快)是)-我们仅保证它们是“正确的”。

    然而; ConcurrentLinkedQueue是一个“免等待”实现,因此这可能与您获得的性能一样。保证Servlet的负载性能(包括并发类的使用)的唯一方法是在负载下对其进行测试。

    10-02 23:58