2012-03-31 50 views
3

我的代碼:塊當前線程

private AtomicBoolean fetched1 = new AtomicBoolean(false); 

    private int rowCount; 

    public int getRowCount() { 
      data.getRealm().exec(new Runnable(){ 
       @Override 
       public void run() { 
        rowCount = data.size(); 
        fetched1.set(true); 
       } 
      }); 
      while(!fetched1.get()){ 
      } 
      fetched1.set(false); 
      return rowCount; 
     } 

似乎對我的工作的權利,但我不熟悉線程(它總是讓我困惑),應我以任何方式執行上述代碼?

回答

7

我應該像上面的代碼那樣做嗎?

這看起來是一個旋轉循環,它將使用不必要的CPU。最好使用waitnotify來指示數據已被提取。喜歡的東西:

private final Object lock = new Object(); 
    private volatile Integer rowCount = null; 
    ... 

     public void run() { 
     rowCount = data.size(); 
     synchronized (lock) { 
      lock.notify(); 
     } 
     } 

    synchronized (lock) { 
    // we loop here in case of race conditions or spurious interrupts 
    while (rowCount == null) { 
     lock.wait(); 
    } 
    } 
    ... 

我不認爲你需要獲取AtomicBoolean可言。你應該使rowCountvolatile然後你可以測試它的值。由於生產者/消費者競爭條件和虛假中斷,while循環是一個很好的模式。

+0

我想你錯過了'fetched.set(true);' – 2012-03-31 14:25:21

+0

是啊謝謝@Peter。我刪除了使用提取的需要。 – Gray 2012-03-31 14:26:51

+0

我會將更新/檢查的字段移動到同步塊中。在這種情況下,它很簡單,但在更復雜的情況下,它將是必要的。 – 2012-03-31 14:28:15

4

你有兩個問題

  • 第一個線程是忙等待,這通常是不可取的。
  • 該模式不能擴展到更多線程,因爲第二個線程可能會嘗試將該值設置爲true。

取而代之,最簡單的模式是鎖定對象並在值更改時等待/通知。