[英]Synchronization work with conditionals? How can I make this code performant and thread safe?
給出以下代碼:
public class SomeClass {
private boolean shouldBlock = false;
private Object resource;
public void handleDrawRequest(Canvas canvas) {
if (!shouldBlock && resource == null)
{
shouldBlock = true;
loadTheResource(); //which takes awhile
shouldBlock = false;
}
else if (shouldBlock && resrouce == null)
{
return; //another thread is taking care of the loading of the resource
//and its not ready yet, so just ignore this request
}
drawResourceOn(canvas);
}
}
如何使此代碼線程安全? 我要完成的工作是讓一個線程只有一個線程來加載資源,而任何其他嘗試同時訪問此代碼的線程都將被丟棄(例如,遵循“ else if”邏輯)直到加載資源。 可能有許多線程試圖同時訪問此代碼,並且我不想同步整個方法,並且要堆積一整堆線程。
public class SomeClass {
private Lock lock = new Lock();
private volatile Object resource;
public void handleDrawRequest(Canvas canvas) {
if( resource==null ) {
if( lock.tryLock() ) {
try {
if( resource==null )
resource = loadResource();
}
finally {
lock.unlock();
}
}
else {
return;
}
}
drawResourceOn(canvas);
}
}
如果您不使resource
volatile
,則線程可以自由地對其進行緩存,並且可能永遠不會讀取更新后的值。 特別是,即使在第一個空檢查之后已加載資源,第二個空檢查也將始終返回true。
您正在尋找一個AtomicBoolean
public class SomeClass {
// AtomicBolean defaults to the value false.
private AtomicBoolean loadingResource = new AtomicBoolean();
private volatile Object resource;
public void handleDrawRequest(Canvas canvas) {
if (resource == null) {
if (loadingResource.compareAndSet(false, true)) {
loadTheResource(); //which takes awhile
} else {
//another thread is taking care of the loading of the resource
//and its not ready yet, so just ignore this request
return;
}
} else {
drawResourceOn(canvas);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.