Java 并发实用程序的用例
我已阅读《Java 并发实践》,这是一本很好的参考书,但我希望看到 java.util.concurrent 包用例的简洁单页摘要。
例如:
- 为什么使用并发集合而不是同步集合?
- 什么时候应该优先使用原子类而不是显式锁定?
- 什么时候应该使用锁而不是同步?
- wait()、notify()、notifyAll() 的替代方法是什么?
- 什么时候应该使用 CompletionService?
有哪些优点/缺点和需要注意的陷阱?
I have read Java Concurrency in Practice and this is a great reference, but I would like to see a concise single page summary of the use cases of the java.util.concurrent package.
For instance:
- Why use a concurrent collection over a synchronized collection?
- When should the atomic classes be preferred over explicit locking?
- When should Locks be used over synchronization?
- What are the alternatives to wait() and notify(), notifyAll()?
- When should a CompletionService be used?
What are the pros/cons and pitfalls to be aware of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为
同步
集合只能保护数据免遭并发访问造成的损坏。这并不意味着同步
集合针对并发访问进行了优化。事实上,远非如此 - 对于compareAndSet
来说,ConcurrentMap.putIfAbsent
是比锁定整个Map
进行读取更好的机制。在我看来,应该始终使用
AtomicInteger
和AtomicLong
类,而不是使用原语手动锁定,因为它们更简洁。考虑一下:与以下内容相比:
不过,我不得不说,这些类由于缺乏可等待性而受到困扰。例如,您经常需要一些同步布尔值,在布尔条件上
等待
。这些在旧的 Doug Lea 并发库中以WaitableBoolean
形式提供,但在juc
中被抛弃,我不确定为什么。这是一个更复杂的问题,因为使用
锁
会带来一些开销。事实上,人们常说在典型情况下使用ReadWriteLock
是没有问题的。必须使用锁的一种场景是资源的锁定及其解锁不能在同一词法范围内完成。synchronized
在此类情况下无能为力。await
、signal
和signalAll
如果不需要在提交计算时访问计算结果的消耗,但计算的完成(或它的结果(或成功)被您的程序所知。例如,这可能是为了监视失败任务(引发异常)的比例,也可能是为了资源清理。
Because a
synchronized
collection only protects data from corruption due to concurrent access. This does not mean that thesynchronized
collections are optimized for concurrent access. Far from it, in fact - aConcurrentMap.putIfAbsent
is a much better mechanism for acompareAndSet
than locking the entireMap
for reads.The
AtomicInteger
andAtomicLong
classes should always be used (in my opinion) over locking by hand with a primitive because they are more concise. Consider:When compared with:
I have to say though, that the classes suffer from their lack of waitability. For example, you often want some synchronized boolean where you
wait
on the boolean condition. These were available asWaitableBoolean
in the old Doug Lea concurrency library but they were jettisoned inj.u.c
, I'm not sure why.This is a more complicated question because usage of
Locks
carries some overhead. In fact, it's often said that there's no pint in using aReadWriteLock
in typical cases. One scenario where locks must be used is where the locking of a resource and its unlocking cannot be done in the same lexical scope.synchronized
is powerless to help in cases such as these.await
,signal
andsignalAll
A completion service is useful in the case where the consumption of a result of a computation does not need to be accessed at the point the computation was submitted but where it is important that the completion of the computation (or its result, or success) be known by your program. This might be, for example, to monitor the proportion of failed tasks (which threw exceptions), or it may be for resource cleanup.
wait()、notify() 和 notifyAll() 的一个非常好的替代方法是完全不使用它们。
这里的 200KLOC 代码库是大量多线程的。我们将负载分散到无数的核心上,并拥有大量的生产者/消费者方案等。
我们的代码中是否有 wait()、notify() 或 notifyAll() 的实例?
零。
我再次强调它是一个高度多线程的应用程序:*闩锁、毒丸、java.util.concurrent.** 以及诸如此类的东西随处。但是wait()、notify()或notifyAll():零个实例。
这是真正的低级内容,应该只在并发实用程序/框架中使用。
来自 Joshua Bloch,在“Effective Java”中,“线程” 章节的开头:
“如果有一个库可以帮助您免于执行低级多线程编程,一定要使用它。”
One very good alternative to wait(), notify() and notifyAll() is to NOT USE THEM AT ALL.
200KLOC codebase here that is heavily multithreaded. We're spreading the load on countless cores and have armies of producers/consumers scheme etc.
Instances of wait(), notify() or notifyAll() in our code?
Zero.
I re-put the emphasis on the fact that it is an heavily multi-threaded application: *latches, poison pills, java.util.concurrent.** and whatnots everywhere. But wait(), notify() or notifyAll(): zero instances.
This is really low-level stuff that should only have its uses in concurrency utilities/frameworks.
From Joshua Bloch, in "Effective Java", at the very beginning of the "Threads" chapter:
"If there is a library that can save you from doing low-level multi-threaded programming, by all means use it."