[英]How synchronize on object without locking?
我已经看到问题如何确定一个对象是否被锁定(同步),以免在Java中阻塞?
但我有问题,我无法找到解决方案。
在我的Web应用程序中是刷新数据容器的过程,这可能需要很长时间。 刷新是在时间间隔内进行的。 当然,当一个刷新仍在容器上工作时,另一个不能(不要破坏容器中的数据)。
我想使用后台线程来刷新容器。 多个后台工作人员可以同时在多个容器上工作(不同的工作人员用于不同的用户会话,每个用户会话可以在其容器中具有不同的数据)。
当然,我可以在worker中进行synchronize(myContainer)
以强制任何其他worker当前没有更新此特定容器。 但我宁愿检查是否有工人正在处理容器并退出,如果是的话。 另外我想不要更改容器的代码,所以我不想在容器类中添加ReentrantLock并锁定它。
因此,worker具有MyContainer
实例,并且想要确定是否有任何其他worker正在刷新此容器实例。
任何想法如何实现?
使用AtomicBoolean
,将此代码放在MyContainer
类中:
AtomicBoolean isRefreshing = new AtomicBoolean(false);
void refresh() {
if ( isRefreshing.compareAndSet( false, true)) {
try {
// refresh
} finally {
isRefreshing.set( false);
}
}
}
如果您无法触摸MyContainer,可能会创建一个包含AtomicBoolean和MyContainer实例的RefreshWrapper。
我会将容器放在ConcurrentLinkedQueue中 ,让工作线程poll
队列,即
Container container;
while((container = queue.poll()) != null) {
container.refresh();
}
然后,您有两个选项,具体取决于容器在刷新时是否正在跟踪。
offer
回队列。 您可以使用if(container.refreshTime < X)
防护来确保不在同一时间间隔内刷新容器两次。 ConcurrentLinkedQueues
和替代它们之间: poll
上queue1
和offer
的刷新容器queue2
,并且当queue1
是空的睡眠,直到下一个时间间隔,在该点poll
上queue2
和offer
在刷新容器queue1
。 offer
回队列。 如果您需要预先检查对象是否尚未被其他线程锁定,则可以使用Thread.holdsLock方法。
如果这还不够,请查看高级锁类 。 这些锁提供了丰富的功能集(检查等待锁定,尝试锁定超时,锁定中断等)。 他们应该提供足够的功能来解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.