I/O 操作の進行状況をユーザーに通知したいと考えています。現時点では、I/O を開始する前に開始し、終了後に停止する内部クラスがあります。次のようになります。
class ProgressUpdater implements Runnable {
private Thread thread;
private long last = 0;
private boolean update = true;
private long size;
public ProgressUpdater(long size) {
this.size = size;
thread = new Thread(this);
}
@Override
public void run() {
while (update) {
if (position > last) {
last = position;
double progress = (double) position / (double) size * 100d;
parent.setProgress((int) progress);
}
}
}
public void start() {
thread.start();
}
public void stop() {
update = false;
parent.setProgress(100);
}
}
parent
は UI への参照position
であり、I/O がどこまで進んだかを表す外部クラスのフィールドです。以前のインクリメントの更新を完了する前に、I/O が終了してアップデーターを停止することがあるため、停止するときに進行状況を 100% に設定します。これだけで 100% になることが保証されます。
現時点では、これは機能し、次のように使用します。
ProgressUpdater updater = new ProgressUpdater(file.length());
updater.start();
//do I/O
//...
updater.stop();
問題は、ループがかなりひどく CPU を消費することです。そこに(待機/通知を使用して)ロックを投げてみましたが、待機/通知の使用に関しては何をしているのかわからないため、スレッドがハングしました。非常に多くの CPU サイクルを使用しないようにするにはどうすればよいですか?