2

スレッドを使用している状況があります。彼女は複数のプロセスを実行するメソッドを呼び出します。スレッドを停止する必要がある「キャンセル」ボタンを使用する必要があります。「while」は使用できません。このプロセスにループがないため、キャンセルされたことを確認します。

元:

    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            controller = new FirstEtapaController();
            execProcess();              
            return null;
        }
    };
    new Thread(task).start();

呼び出し方法

   private void execProcess() {
   Thread thread = new Thread(new Runnable() {

        public void run() {
    getController().execMhetod();
    refreshTable();
        }
    });
    thread.start();
    thread.join();
};

つまり、「ExecMethod」がすでに実行されている場合でも、このプロセスを停止する必要があります。数分かかるため、停止する必要があり、彼が終了するのを待つ必要がなく、他のプロセスが続行されません。

このプロセスは私の DAO で反復を行うことを思い出してください。

4

4 に答える 4

2

唯一の方法 (行儀の良い方法) は、生成されたスレッドに論理ポイントを追加して、中断された状態をチェックすることです。組み込みのThread.interrupt()メカニズムを使用するか、何らかの形式のスレッドセーフ変数 ( AtomicBoolean?) または何らかのセマフォを使用して独自のロジックを追加するかを選択できます。

を使用するThread.interrupt()と、Thread.wait() や、同期が必要なメソッドや java.util.concurrent.* クラスを使用するその他のメソッドなど、特定の条件が発生したときに、子プロセスによって InterruptedException がスローされます。

いずれにせよ、スレッドで を処理する必要があります (既にあるはずInterruptedExceptionsです) が、おそらく、子プロセスに通常の「チェック」を入れて、中断された状態を探す必要があります ( を使用できますThread.isInterrupted())

このJavaでのInterruptedExceptionの処理を読む価値があります

于 2013-08-22T19:05:56.733 に答える
1

生の Thread の代わりにExecutorServiceを使用すると、スレッドを制御するための追加のメソッド/レバーが多数作成されます。そのうちの 1 つは、スレッドを強制終了するためにshutdownAll()使用され、次の方法でThread.interrupt()スレッドのステータスを確認できます。isTerminated()

于 2013-08-22T19:07:57.750 に答える
0

ユーザー インターフェイスはワーカー スレッドが終了するのを待つ必要がないので、あまり心配する必要はありません。

残念ながら、Thread.destroy() と Thread.stop() は実装が不適切なため非推奨です。Java スレッドに代わる優れた「sig-kill」タイプはないと思います。なんらかのアボート フラグが重要な場合は、ワーカを再コーディングして、何らかのアボート フラグをチェックする必要があります。それ以外の場合は、少し CPU を浪費させてください。(「その保存をキャンセルすることはできません -- 私は既に実行しました!」、事実上)

于 2013-08-22T19:11:05.373 に答える
0

タスクをキャンセルできるかどうかは、実際にはその実装に依存します。通常、フラグを継続するかどうかを断続的にチェックします。

このようなフラグを自分で実装し、それを設定するメソッドを実装できます:

private volatile boolean shouldStop;

public void cancel() {
    shouldStop = true;
}

@Override
public void run() {
    while (!shouldStop) {
        // do work
    }
}

しかし、スレッドにはすでにフラグが付いています: 割り込みフラグです。また、必ずしもスレッドをキャンセルするために使用されるわけではありませんが、まさにその目的で使用されるのが一般的です。実際、標準のExecutorService実装では、スレッドを中断してスレッドをキャンセルしようとします。

それとは別に、いくつかのブロッキング メソッド (スレッドを状態BLOCKEDまたはWAITING状態にするメソッド) は、スレッドが中断されたときに をスローし、InterruptedExceptionその時点でRUNNABLE再び になります。これは、ブール値フラグを使用した以前のアプローチでは達成できないことです。

したがって、割り込みを使用してタスクをキャンセルできるようにする方が良い方法です。また、その cancel() メソッドももう必要ありません。

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        // do work
    }
}

おまけとして、スレッドを知っているコードは、スレッドをキャンセルする方法を知っています。ExecutorService標準実装を含みます。

InterruptedExceptionをキャッチすると中断フラグがクリアされるため、 をキャッチするときは注意が必要です。例外をキャッチするときは常に中断フラグを復元することをお勧めします。これにより、クライアントは自分が行っていることをやめる時が来たこともわかります。

private BlockingQueue<Integer> queue;

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {

        try {
            Integer id = queue.take(); // blocking method

            // do work
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

    }
}

スレッドをキャンセルするには、Threadオブジェクトへの参照を保持して呼び出しますinterrupt()

Thread thread = new Thread(new InterruptibleTask());
thread.start();

// some time after :

thread.interrupt();

しかし、より洗練されたアプローチは、オブジェクトを介してタスク (タスクが実行されている特定のスレッドではなく) を監視するFutureことです。Runnableこれを行うには、またはCallableを でラップしますFutureTask

RunnableFuture<Void> task = new FutureTask<>(new InterruptibleTask(), null);
new Thread(task).start();

// some time after :

task.cancel(true); // true indicating interruption may be used to cancel.

AFutureは、タスクを制御する上で重要です。完了するまで待機し、オプションでタスクが計算した値を受け取ることができます。

try {
    String value = future.get(); // return value is generically typed String is just as example.
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // since future.get() blocks
} catch (ExecutionException e) {
    logger.log(Level.SEVERE, "Exception on worker thread", e.getCause()); // the ExecutionException's cause is the Exception that occurred in the Task
}

複数のタスク (または 1 つだけでも) がある場合は、 ExecutorService を使用する価値があります。

ExecutorService pool = Executors.newCachedThreadPool();

Future<?> submit = pool.submit(new InterruptibleTask());

pool.shutdownNow(); // depending on ExecutorService implementation this will cancel all tasks for you, the ones Executors returns do.
于 2013-08-22T21:02:18.917 に答える