簡體   English   中英

有條件的同步工作? 如何使此代碼性能和線程安全?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM