[英]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.