java 等待……通知低级同步的最佳选择是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4912165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:35:41  来源:igfitidea点击:

What's the best alternative to wait...notify for low level synchronization?

javamultithreadingconcurrency

提问by ripper234

As far as I know, wait()and notify()have been replaced with better concurrency mechanisms. So, what better alternative would you choose, say for implementing a synchronized queue?

据我所知,wait()notify()已替换为更好的并发机制。那么,你会选择什么更好的替代方案,比如实现同步队列

In what sense exactly are they "better"?

他们究竟在什么意义上“更好”?

Edit: This ("implement a synchronous queue") is an interview question. An acceptable answer cannot use BlockingQueue or other queue implementation. It might, however, use other synchronization constructs such as CountDownLatch. I do not have an exhaustive list of allowed and forbidden classes - use your heads.

编辑:这个(“实现同步队列”)是一个面试问题。可接受的答案不能使用 BlockingQueue 或其他队列实现。但是,它可能会使用其他同步构造,例如 CountDownLatch。我没有一份详尽的允许和禁止类的清单 - 用你的头脑。

回答by Jed Wesley-Smith

synchronized/wait()/notify()/notifyAll()have been directly replaced by the Lock class methods lock()/unlock()/newCondition()and Condition's await()/signal()/signalAll().

synchronized/wait()/notify()/notifyAll()已被 Lock 类方法lock()/unlock()/newCondition()和 Condition 的await()/signal()/signalAll().

There are several benefits to these, for a start allowing additional semantics such as fairness policies, as well as features such as distributed locking. The support for multiple Conditionobjects allows for much finer-grained signalling as well as uninterruptible waiting and waiting until some time etc.

这些有几个好处,首先允许额外的语义,如公平策略,以及分布式锁定等功能。对多个Condition对象的支持允许更细粒度的信令以及不间断的等待和等待一段时间等。

For instance, the linked code has separate objects it attempts to use for signalling (which will fail due to the fact that the relevant monitors aren't held when waiting). This is directly replaceable by the use of a single Lock with multiple conditions.

例如,链接的代码有单独的对象,它试图用于发出信号(由于等待时相关监视器没有被保持,这将失败)。这可以通过使用具有多个条件的单个 Lock 来直接替换。

In terms of improvements, the additional functionality may be of value. In Java5 the explicit Lock implementations actually performed better than the JVM monitors, but they basically nicked Doug Lea's code for the JVM and performance is now roughly equivalent.

在改进方面,附加功能可能是有价值的。在 Java5 中,显式的 Lock 实现实际上比 JVM 监视器表现得更好,但它们基本上削弱了 Doug Lea 的 JVM 代码,现在性能大致相当。

回答by Lachezar Balev

There are pretty much implementations already existing in the java.util.concurrentpackage. E.g. - ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue.

java.util.concurrent包中已经存在很多实现。例如 - ArrayBlockingQueueDelayQueueLinkedBlockingQueuePriorityBlockingQueueSynchronousQueue

Also wait()and notify()have not been replaced. New utilities have been introduced that provide additional functionalities and performance benefits. See for example the java.util.concurrent.lockspackage.

wait()notify()没有被取代。引入了新的实用程序,可提供额外的功能和性能优势。参见例如java.util.concurrent.locks包。

I would recommend you to read thisintroduction. It provides a high overview that should answer your question.

我建议你阅读这篇介绍。它提供了一个高度的概述,应该可以回答您的问题。

Cheers.

干杯。

Edit 1:Ok, then for example you can use an implementation of java.util.concurrent.locks .Lockto implement a dequeue operation that times-out and in the same time grants fairness to the threads accessing the queue. Such implementation is ReentrantLockwhich has a constructor that accepts the fairness policy. The timed tryLock()favors this property. Also you can add some debugging support for counting the waiting threads on the queue, etc. This would be much more difficult to implement simply with wait()and notify()I assume.

编辑 1:好的,例如,您可以使用 的实现java.util.concurrent.locks .Lock来实现一个出队操作,该操作超时并同时为访问队列的线程授予公平性。这种实现ReentrantLock具有接受公平策略的构造函数。时间tryLock()有利于这个属性。你还可以添加一些调试支持统计关于队列中等待的线程,等等。这将更加难以实施简单地wait()notify()我承担。

In conclusion ReentrantLockis "better" than the low level counterparts in its extended capabilities. The basic behavior is the same though. If you do not need these extras wait()and notify()are still acceptable alternative.

总之,ReentrantLock在其扩展能力方面比低级同行“更好”。但基本行为是相同的。如果你不需要这些额外的东西wait()并且notify()仍然是可以接受的替代品。

回答by maerics

Reading the source of the ArrayBlockingQueueimplementation reveals the use of Conditionsas a replacement for the Object monitor methods "wait/notify/notifyAll". Also, a ReentrantLockis used instead of the "synchronized" keyword to attain similar mutual exclusion behavior and semantics. So it seems the java.util.concurrent.lockspackage is what you're looking for. These new interfaces are better because they provide additional functionality not possible with the original synchronization and locking constructs, such as multiple wait-sets and selective read or write locks (rather than always both read andwrite).

阅读ArrayBlockingQueue实现的源代码揭示了使用条件作为对象监视器方法“wait/notify/notifyAll”的替代。此外,使用ReentrantLock代替“同步”关键字以获得类似的互斥行为和语义。所以看起来java.util.concurrent.locks包就是你要找的。这些新接口更好,因为它们提供了原始同步和锁定构造无法实现的附加功能,例如多个等待集和选择性读取或写入锁定(而不是总是读取写入)。

The java.util.concurrent.atomicpackage also provides interfaces to compare-and-swapinstructions which are useful for non-blocking algorithms, which are potentially much faster than their blocking alternatives but have their own challenges.

java.util.concurrent.atomic中的包还提供接口来比较并交换指令是有用的非阻塞算法,这是有可能比他们堵方案要快得多,但有自己的挑战。

回答by Kaushik Lele

park() unpark() methods of LockSupport class seems to be useful in this case. I also faced same questions and while searching on net, found a clue in this discussion.

在这种情况下,LockSupport 类的 park() unpark() 方法似乎很有用。我也遇到了同样的问题,在网上搜索时,在这个讨论中找到了线索。

Synchronization vs Lock

同步与锁定

But I need to understand the concepts further to create a sample application.

但我需要进一步了解这些概念才能创建示例应用程序。

回答by user1776290

How about using Semaphore from the Concurrent package? Using a binary Semaphore as a intrinsic lock and two counting Semaphores to set a bound on the size of the queue?

使用 Concurrent 包中的 Semaphore 怎么样?使用二进制信号量作为内在锁和两个计数信号量来设置队列大小的界限?