1

私のコード ベースは非常に大きいので、ここではできるだけ簡潔にまとめます。

私は、 a がRunnablea 内で実行を終了すると、 と のThread両方が破棄されると仮定しています。これは、 内のコードが線形コードであるためです。おそらくいくつかの関数呼び出しですが、間違いなくループはありません。ThreadRunnableRunnable

問題は、Thread実行中のままであることですが、実行すべきではないと思います。

の作成RunnableProcessor:

Controller.getInstance().getNamedThreadFactory().addThreadName("EST: " + runnableProcessor.toString());
Controller.getInstance().getExecutorService().execute(runnableProcessor);

RunnableProcessorクラス:

public class RunnableProcessor<T> implements Runnable {
    private final Processor<T> processor;
    private final T object;

    public RunnableProcessor(final Processor<T> processor, final T object) {
        this.processor = processor;
        this.object = object;
    }

    @Override
    public void run() {
        processor.process(object);
    }

    @Override
    public String toString() {
        return "RunnableProcessor(\"" + processor + "\", \"" + object.toString() + "\")";
    }
}

そのような の例Processor、つまりInputProcessor:

public class InputProcessor implements Processor<File> {
    private static final String PDF = "pdf";

    @Override
    public void process(File file) {
        if (new CustomPath(file).getExtension().equalsIgnoreCase(PDF)) {
            processPdf(file);
        }
        else {
            processImage(file);
        }
    }

    private void processPdf(final File file) {
        System.out.println("Processing " + file.toString());
        FileEditor.convert(file);
        Utils.move(file.toPath(), new File(Controller.DONE_URL + File.separator + file.getName()).toPath());
        System.out.println("Processed");
    }

    private void processImage(final File file) {
        //Skew detection
        System.out.println("Rotating " + file.toString());
        SkewDetector skewDetector = new SkewDetector(file);
        File rotatedFile = skewDetector.detect();
        Utils.move(rotatedFile.toPath(), new File(Controller.ROTATED_INPUT_URL + File.separator + rotatedFile.getName()).toPath());
        System.out.println("Rotated");
    }

    @Override
    public String toString() {
        return "InputProcessor";
    }
}

コード内の何も実行をブロックしません。つまり、この場合、特定の文字列ProcessedまたはRotatedすべてが に出力されます。System.outその後、特定の文字列はThreadまだ停止しません。これはたとえば、実行が終了したにもかかわらず、まだ生きているスレッドの 1 つです。Runnable名前は:EST: RunnableProcessor("InputProcessor", "D:\OCR\renamed_input\682-converted.tiff")です。

スレッドの動作は、2 分間にわたって測定されたものですが、興味深いようです: 次の順序に従います: 短時間実行、短時間監視、長時間実行、クイック モニター、短時間実行、非常に長い待機、比較的短い実行、非常に長い待機、比較的短い走って、待って(永遠まで?)。

正確に何が起こっているのかを理解するのを手伝ってくれる人はいますか?

4

3 に答える 3

2

Executor サービスを使用しているようです。タスクごとに新しいスレッドを作成するように実装できますが、明らかにあなたの場合は、スレッドが新しいタスクの実行を待機するスレッドプールを使用して実装されています。ドキュメントによると、これはパフォーマンスを向上させるために行われます。

いずれにせよ、executor サービスの内部動作に依存するべきではありません。タスクが完了したときに通知を受ける必要がある場合は、タスクまたはラッパーを監視することをお勧めします。

新しいラッパーを作成し、(スレッドのステータス) をポーリングしているように見える場合は、次のように簡単にできます。

void run() {
    innerRunner.run();  // the wrapped runner
    doneFlag = true;    // a boolean indicating the status
}
于 2013-11-13T08:38:06.793 に答える
1

電話する必要があるかもしれません

Controller.getInstance().getExecutorService().shutdown();
Controller.getInstance().getExecutorService().awaitTermination();

スレッドプールをシャットダウンするには。

于 2013-11-13T08:36:56.737 に答える