2012-03-31 7 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);が見つからないと思います。 –

+0

@Peterに感謝します。私はフェッチされたものを使う必要を一掃しました。 – Gray

+0

フィールドを更新/チェックインして同期ブロックに移しました。この場合、シンプルですが、より複雑なケースでは必要になります。 –

4

次の2つの問題

  • 最初のスレッドは、通常は望ましくないビジーウェイト、あるを持っています。
  • 2番目のスレッドが値をtrueに設定しようとする可能性があるため、パターンを複数のスレッドに拡張することはできません。

代わりに最も単純なパターンは、オブジェクトをロックし、値が変更されたときに待機/通知することです。

関連する問題