你基本上是在问三个不同的问题(其中两个是明确的,一个是隐含的)。他们在这里,我的答案是:
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
的调用吗?
因为这是一个无限的实现,所以可以保证无论同时发出多少个请求,队列都不会丢失这些请求(因为队列的并发性...你可能会用完内存或一些类似的...但队列实现本身不会是你的限制因素。在 Web 应用程序中,还有其他机会“丢失”请求,但队列的同步(或缺少同步)不会是您的原因。
3. java.util.ConcurrentLinkedQueue
的性能是否足够好?
通常,当我们谈论并发性时,我们谈论“正确性”。我的意思是,Concurrent 类保证它们是线程安全的(或者对死锁、饥饿等具有健壮性)。当我们谈论这一点时,我们并没有对性能做出任何保证(对集合的调用速度有多快) - 我们只是保证它们是“正确的”。
但是;ConcurrentLinkedQueue是一个“无等待”的实现,所以这可能是你能得到的最好的。保证 servlet 的加载性能(包括使用并发类)的唯一方法是在加载下对其进行测试。