ThreadPoolExecutorを使用して作成されたタスクの実行時間を制限する方法に関する詳細情報を見つけようとしています。
たとえば、時間が経過すると (たとえば 1m)、スレッドは自動的に終了し、null 値を返します。ここでの重要な点は、スレッドの終了を待機することでメイン スレッド (この例では UI スレッド) をブロックしてはならないということです。
getメソッドを使用できることはわかっていますが、アプリケーションがブロックされます。
1分間スリープしてからメインスレッドで割り込みを呼び出す追加の内部スレッドを実行することを考えていました。
サンプル コードを添付しました。これは良いアイデアのように見えますが、それが理にかなっている場合は別の目で確認する必要があります。
public abstract class AbstractTask<T> implements Callable<T> {
private final class StopRunningThread implements Runnable {
/**
* Holds the main thread to interrupt. Cannot be null.
*/
private final Thread mMain;
public StopRunningThread(final Thread main) {
mMain = main;
}
@Override
public void run() {
try {
Thread.sleep(60 * 1000);
// Stop it.
mMain.interrupt();
} catch (final InterruptedException exception) {
// Ignore.
}
}
}
call() は ThreadPool 経由で呼び出されます
public T call() {
try {
// Before running any task initialize the result so that the user
// won't
// think he/she has something.
mResult = null;
mException = null;
// Stop running thread.
mStopThread = new Thread(new StopRunningThread(
Thread.currentThread()));
mStopThread.start();
mResult = execute(); <-- A subclass implements this one
} catch (final Exception e) {
// An error occurred, ignore any result.
mResult = null;
mException = e;
// Log it.
Ln.e(e);
}
// In case it's out of memory do a special catch.
catch (final OutOfMemoryError e) {
// An error occurred, ignore any result.
mResult = null;
mException = new UncheckedException(e);
// Log it.
Ln.e(e);
} finally {
// Stop counting.
mStopThread.interrupt();
}
return mResult;
}
私が恐れている点がいくつかあります:
- execute() に例外があり、その直後に外部スレッドが中断された場合、例外をキャッチすることはありません。
- メモリ/CPU の消費量。スレッド プールを使用して、新しいスレッドの作成を回避しています。
同じ機能を達成するためのより良いアイデアはありますか?