Java 并发实用程序的用例

发布于 2024-08-04 00:40:07 字数 291 浏览 4 评论 0原文

我已阅读《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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

假扮的天使 2024-08-11 00:40:07
  • 为什么使用并发集合而不是同步集合?

因为同步集合只能保护数据免遭并发访问造成的损坏。这并不意味着同步集合针对并发访问进行了优化。事实上,远非如此 - 对于 compareAndSet 来说,ConcurrentMap.putIfAbsent 是比锁定整个 Map 进行读取更好的机制。

  • 什么时候应该优先使用原子类而不是显式锁定?

在我看来,应该始终使用 AtomicIntegerAtomicLong 类,而不是使用原语手动锁定,因为它们更简洁。考虑一下:

synchronized (lock) { 
    int old = counter;
    counter++;
    return old;
}

与以下内容相比:

int old = counter.getAndIncrement();

不过,我不得不说,这些类由于缺乏可等待性而受到困扰。例如,您经常需要一些同步布尔值,在布尔条件上等待。这些在旧的 Doug Lea 并发库中以 WaitableBoolean 形式提供,但在 juc 中被抛弃,我不确定为什么。

  • 什么时候应该使用锁而不是同步?

这是一个更复杂的问题,因为使用会带来一些开销。事实上,人们常说在典型情况下使用ReadWriteLock是没有问题的。必须使用锁的一种场景是资源的锁定及其解锁不能在同一词法范围内完成synchronized 在此类情况下无能为力。

  • wait()、notify()、notifyAll() 的替代方法是什么?

awaitsignalsignalAll

  • 何时应使用 CompletionService?

如果不需要在提交计算时访问计算结果的消耗,但计算的完成(或它的结果(或成功)被您的程序所知。例如,这可能是为了监视失败任务(引发异常)的比例,也可能是为了资源清理。

  • Why use a concurrent collection over a synchronized collection?

Because a synchronized collection only protects data from corruption due to concurrent access. This does not mean that the synchronized collections are optimized for concurrent access. Far from it, in fact - a ConcurrentMap.putIfAbsent is a much better mechanism for a compareAndSet than locking the entire Map for reads.

  • When should the atomic classes be preferred over explicit locking?

The AtomicInteger and AtomicLong classes should always be used (in my opinion) over locking by hand with a primitive because they are more concise. Consider:

synchronized (lock) { 
    int old = counter;
    counter++;
    return old;
}

When compared with:

int old = counter.getAndIncrement();

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 as WaitableBoolean in the old Doug Lea concurrency library but they were jettisoned in j.u.c, I'm not sure why.

  • When should Locks be used over synchronization?

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 a ReadWriteLock 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.

  • What are the alternatives to wait() and notify(), notifyAll()?

await, signal and signalAll

  • When should a CompletionService be used?

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.

风吹过旳痕迹 2024-08-11 00:40:07
What are the alternatives to wait() and notify(), notifyAll()

wait()、notify()notifyAll() 的一个非常好的替代方法是完全不使用它们

这里的 200KLOC 代码库是大量多线程的。我们将负载分散到无数的核心上,并拥有大量的生产者/消费者方案等。

我们的代码中是否有 wait()、notify()notifyAll() 的实例?

零。

我再次强调它是一个高度多线程的应用程序:*闩锁、毒丸、java.util.concurrent.** 以及诸如此类的东西随处。但是wait()、notify()notifyAll():零个实例。

这是真正的低级内容,应该只在并发实用程序/框架中使用。

来自 Joshua Bloch,在“Effective Java”中,“线程” 章节的开头:

“如果有一个库可以帮助您免于执行低级多线程编程,一定要使用它。”

What are the alternatives to wait() and notify(), notifyAll()

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."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文