私はあなたの賢明さに提出したいGUIの問題からのユースケースを持っています。Javaでの巧妙な非同期再描画
ユースケースは、私はいくつかのパラメータにGUIで設定したユーザに応じて演算結果を表示するGUIを有します。たとえば、ユーザーがスライダーを動かすと、いくつかのイベントが発生し、すべてが新しい計算をトリガーします。ユーザーがスライダの値をAからBに調整すると、数十のイベントが発生します。
しかし、計算には数秒かかることがありますが、スライダの調整では100ミリ秒ごとにイベントが発生する可能性があります。
これらのイベントをリッスンする適切なスレッドを作成する方法と、結果の再描画が活発に行われるようにフィルターをかける方法はありますか?理想的には、最初の変更イベントが受信されると直ちに新しい計算を開始するようなものを希望します。
- 新しいイベントが受信された場合は最初の計算をキャンセルし、新しいパラメータで新しいイベントを開始します。
- ただし、最後に完了した計算が最後に更新されたパラメータを持つ計算である必要があるため、最後のイベントが失われないことを確認してください。
私は
を試してみましたが、どのような計算をトリガするためにあまりにも多くのイベントを防止アップデータスレッドのこの低レベルのアプローチを提案している私の友人(A.カルドナ)。私はここ(GPL)のそれを、コピー&ペースト:
彼はスレッドを拡張するクラスでこれを置く:
public void doUpdate() {
if (isInterrupted())
return;
synchronized (this) {
request++;
notify();
}
}
public void quit() {
interrupt();
synchronized (this) {
notify();
}
}
public void run() {
while (!isInterrupted()) {
try {
final long r;
synchronized (this) {
r = request;
}
// Call refreshable update from this thread
if (r > 0)
refresh(); // Will trigger re-computation
synchronized (this) {
if (r == request) {
request = 0; // reset
wait();
}
// else loop through to update again
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void refresh() {
// Execute computation and paint it
...
}
イベントは、パラメータが変更されたことを示すGUIによって送信されたすべての時、私たちは呼んでupdater.doUpdate()
。これにより、メソッドrefresh()
はあまり呼び出されません。 しかし、私はこれをコントロールできません。
別の方法ですか?
jaca.concurrentクラスを使用する別の方法があるのだろうかと思っていました。しかし、私は、Executorsフレームワークで、私が最初に始めるべきものを選ぶことはできませんでした。
似たような経験をしている方もいらっしゃいますか?
ありがとう
良い解決策。しかし、 'worker1.cancel()'、 'worker1.done()'がまだ実行されていて、 'worker2.done()'の後に実行できる小さなチャンスがあるかどうかは不明です。つまり、古い結果が上書きされます新しい結果。ここでもう少し調査が必要です。 – ZhongYu
これは、リクエストを一括処理する方法の問題を解決しないため、短期間にスレッドを何度もキャンセルして再起動する状況を回避します。 –
リクエストをキャンセルすることは避けられないと思います。リクエストが最後かどうかわからないからです。確かに、より多くのリクエストが来ているかどうかを確認するために、労働者を解雇する前にちょっと待つことができますが、それは単に更新を遅くするだけです。 'worker2.doInBackground()'は 'worker1.cancel()'よりもはるかに時間がかかるので、可能であれば、 –