0

私は、常に更新されているデータを描画したいプログラムを持っています (ちなみに microhlone-line-data です)。データは長さ 8000 の double の配列です。paint メソッドのテイク間でオーバーライドされるデータの「損失」についてはあまり気にしません。

私の単純な実装では、描画ルーチンの進行中にオーディオデータが更新される同期の問題があることが明らかになりました。

また、Java と Java の Concurrency パッケージについて少し古くなっていることも承知していますが、私の最初の対応は、共有データ コードの周りに同期ブロックを配置することでした。当然のことながら、これによりグラフィック スレッドがブロックされることがあるので、これを行うにはもっと良い方法があると思います。

基本的に、私は同期の経験があまりなく、どこかで物事を少し台​​無しにしています。これらの問題をよりよく理解している人が、グラフィックス スレッドをブロックしない、より洗練されたソリューションを提案できるのではないでしょうか?

私の素朴なコード:

Object lock = new Object();
double[] audio = new double[8000]

// array size is always exactly 8000
public update( double[] audio ) {
    synchronized( lock ) {
       this.audio=audio; // and some brief processing
    }
    repaint();
}

public void paint( Graphics g ) {
    synchronized( lock ) {
        // draw the contents of this.audio
    }
}
4

1 に答える 1

0

自問自答します。より知的な人がより良いものを提供できない限り、私はルーチンの最初にオーディオ配列への参照を保存し、そこから引き出すだけです。その後、オーディオ バッファへの更新は別の配列で計算を行い、次にワンステップで this.audio を新しい配列に割り当てます。

動作しているように見えますが、ペイント ルーチンはときどきちらつきますが、シンクロナイズド ブロッキングのために約 10% の時間で非常に顕著に点滅していた以前とはまったく異なります。音声データは、描画ルーチンの途中でも更新されません。そう... 問題は解決しました。おそらく。

double[] audio = new double[8000]

// array size is always exactly 8000
public update( double[] audio ) {
   // do any brief processing
   this.audio=audio; // the reference is re-assigned in one step

repaint();
}

public void paint( Graphics g ) {
    audioNow = this.audio; // save the reference
    // draw the contents of audioNow (not this.audio)
}
于 2012-12-01T21:38:53.150 に答える