コードをニラむ夜

このエントリで引用してるサンプル。JAG 沖縄支部の id:ttmmrr さんから volatile な属性の件についてもコメントにてフォロー頂く。
例えば以下なコードか。

               while (!this.isRecording) {
                    try {
                         mutex.wait();
                    } catch (InterruptedException e) {
                         throw new IllegalStateException("Wait() interrupted!", e);
                    }
               }

確かにループの中で isRecording 属性に値を代入してる訳ではない。しかも volatile な属性は mutex 取らないとアクセス不能。面白いなぁ、とは言え未だに何故にこっちは上手く動いてあっちは上手く動かないか、なナニに至ってない部分が微妙ッス。

現状

Activity のサブクラスを

  • 20 秒 wait しないで
  • setRecording(false) とか join とかは onDestroy でナニ

という形に改修してますが、一応正常動作しているとの事。

なんとなくな感想

なんですが、最初のソレがポイントな気はしています。

  • Activity 側で
    • thread なオブジェクトに start() をナニ
    • Recorder なオブジェクトに setRecording(true) をナニ

上記で Recorder なオブジェクトの run() が起動されます。冒頭の処理が以下。

          synchronized (mutex) {
               while (!this.isRecording) {
                    try {
                         mutex.wait();
                    } catch (InterruptedException e) {
                         throw new IllegalStateException("Wait() interrupted!", e);
                    }
               }
          }

上記、

  • mutex 取って
  • isRecording が true になるまで busy loop
  • mutex.wait() 呼び出しでお休み

で、setRecording(true) される事で以下な処理

     public void setRecording(boolean isRecording) {
          synchronized (mutex) {
               this.isRecording = isRecording;
               if (this.isRecording) {
                    mutex.notify();
               }
          }
     }
  • mutex 取って
    • ちなみに wait で mutex は破棄
  • 引数を isRecording 属性にセット
  • 値が true なら notify でお休みになっておられるナニを起動

上手に同期を取っているように見えます。素晴しい。

今からリポジトリを確認して jni なソースが盛り込まれてたら *.mk とかをナニする方向ッス。