确保 Java 同步锁按顺序获取?
我们有两个线程通过同步方法访问一个列表。我们能否
a) 依靠运行时来确保每个人都将根据他们尝试的顺序接收对方法的访问权限,或者
b) 虚拟机是否遵循任何其他规则
c) 是否有更好的方法来序列化请求?
we have two threads accessing one list via a synchronized method. Can we
a) rely on the run time to make sure that each of them will receive access to the method based on the order they tried to or
b) does the VM follow any other rules
c) is there a better way to serialize the requests?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不,synchronized 将以任何顺序提供访问权限(取决于 JVM 实现)。在某些情况下,这甚至可能导致线程饥饿。
您可以使用 ReentrantLock< 来确保顺序/a> (自 Java 5.0 起)带有
fair=true
选项。 (Lock lock = new ReentrantLock(true);
)No, synchronized will give access in any order (Depends on the JVM implementation). This could even cause Threads to starve in some scenarios.
You can ensure the order by using ReentrantLock (since Java 5.0) with the
fair=true
option. (Lock lock = new ReentrantLock(true);
)不,您无法确定对同步方法的两次调用是否会按顺序发生。该顺序未指定且依赖于实现。
这是在 17.1 锁 部分中定义的JLS。请注意,这没有说明等待锁的线程应该获得访问的顺序。
No you cannot be sure that two calls to a synchronized method will occur in order. The order is unspecified and implementation dependent.
This is defined in the 17.1 Locks section of the JLS. Notice that is says nothing about the order in which threads waiting on a lock should gain access.
您不能依赖每个线程调用特定方法的顺序。如果只有两个线程可能是的。但想象一下,如果有 3 个线程并且 1 个线程已经获得了访问权限。其他 2 个线程在尝试访问时将等待,其中任何一个线程都可以被授予访问权限,并且这不取决于它们调用此方法的顺序。
所以,不建议依赖命令。
You can't rely on the order in which the particular method is called from each threads. If it is only two threads may be yes. But imagine if there are 3 threads and 1 thread already acquired access. The other 2 threads when they try to access will wait and any one of them can be awarded the access, and this does not depend on the order in which they called this method.
So, it is not suggested to rely on the order.
您是否有机会使用列表作为队列,即使用模式是否看起来像这样?
如果是这样,您可能需要查看
BlockingQueue
接口而不是使用您自己的锁定方案。实现(如ArrayBlockingQueue
)具有公平性等设置。
Are you by any chance using the list as a queue, i.e., does the usage pattern look something like this?
If so, you may want to look at the
BlockingQueue
interface instead of using your own locking schemes. The implementations (likeArrayBlockingQueue
) have settings for fairness and more.我总是将同步保留给应用程序服务器或引擎,除非定义自己的强度
I always leave syncs to app server or engine unless defining own intensity
我已经用几种仪器解决了类似的问题。我试图解决的问题是乒乓服务。两个线程,一个打印 Ping,另一个打印 Pong。但它们必须是连续的。 (没有双 Ping 或双 Pong)
我将在这里放置一个实现,但您可以查看其他实现(目前有 6 或 7 种不同的方式)
https://github.com/tugrulkarakaya/pingpong
I have solved similar problem with couple of instrument. The problem I was trying to solve is Ping Pong Service. two thread one prints Ping and the other prints Pong. but They have to be SEQUENTIAL. (no double Ping or double Pong)
I will put one of the Implementation here but you can have a look other implementation (6 or 7 different way for now)
https://github.com/tugrulkarakaya/pingpong
是的。
如果通过一种同步方法访问该列表,则来自多个线程的并发请求将被序列化。
Yes.
If access to the list is via one synchronized method, concurrent requests from multiple threads will be serialized.