确保按顺序采用Java同步锁?
-
05-07-2019 - |
题
我们有两个线程通过synchronized方法访问一个列表。我们可以吗
a)依靠运行时间来确保每个人都可以根据他们尝试的顺序获得对该方法的访问权或
b)VM是否遵循任何其他规则
c)是否有更好的方法来序列化请求?
解决方案
不,synchronized将以任何顺序提供访问权限(取决于JVM实现)。这甚至可能导致线程在某些情况下挨饿。
您可以使用 ReentrantLock (自Java 5.0起),带有 fair = true
选项。 ( Lock lock = new ReentrantLock(true);
)
其他提示
不,您无法确定是否会按顺序对同步方法进行两次调用。订单未指定且依赖于实现。
这是在 17.1 Locks JLS的部分。请注意,没有提及等待锁的线程应该获得访问权的顺序。
您不能依赖于从每个线程调用特定方法的顺序。如果只有两个线程可能是肯定的。但想象一下,如果有3个线程和1个线程已经获得访问权限。当他们尝试访问时,其他2个线程将等待,并且其中任何一个都可以获得访问权限,这并不取决于他们调用此方法的顺序。 因此,不建议依赖订单。
c)是否有更好的方法来序列化请求?
您是否有可能将列表用作队列,即使用模式是否看起来像这样?
while (some condition) { synchronized(theList){ anItem = get and remove an element from theList } do some work with anItem }
如果是这样,你可能想看一下 BlockingQueue
接口,而不是使用您自己的锁定方案。实现(如 ArrayBlockingQueue 代码>
)具有公平性等设置。
我总是将同步发送到应用服务器或引擎,除非定义自己的强度
是
如果通过一个同步方法访问列表,则将序列化来自多个线程的并发请求。
不隶属于 StackOverflow