「こんにちは、アミーゴ! ここで、あなたがすでに抱いているか、あるいはすぐに抱くであろう興味深い質問があります。実行中のスレッドを停止するにはどうすればよいですか?

ユーザーがプログラムに「インターネットからファイルをダウンロード」するように指示したとします。メインスレッドは、このジョブ用に別の子スレッドを作成し、ファイルをダウンロードするために必要なすべてのアクションを含む run メソッドを持つオブジェクトをそれに渡します。

しかし、ユーザーは突然考えを変えます。彼はファイルをダウンロードしたくないのです。ジョブをキャンセルしてスレッドを停止するにはどうすればよいでしょうか?

「はい、その方法を教えてください。」

できません。これが最も一般的で最も正しい答えです。スレッドを停止することはできません。スレッド自体を停止できるのはスレッドだけです。

ただし、スレッドにシグナルを送信して、何らかの方法で、作業を実行する必要がなくなり、終了する必要があることをスレッドに伝えることができます。メインスレッドが main メソッドから戻ることによって終了するのと同様に、子スレッドも run メソッドから戻ることによって終了します。

「それを行うための最良の方法は何ですか?」

「ブール値などの変数を追加できます。 trueの場合、スレッドが実行されます。 falseの場合 、スレッドは終了します。たとえば、次のようになります。」

コード 説明
class Clock implements Runnable
{
public void run()
{
while (true)
{
Thread.sleep(1000);
System.out.println("Tick");

if (!ClockManager.isClockRun)
return;
}
}
}

Clock クラスは、コンソールに «Tick» を 1 秒に 1 回永久に書き込みます。

ClockManager.isClockRun が false の場合、run メソッドは終了します。

class ClockManager
{
public static boolean isClockRun = true;
public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
isClockRun = false;
}

}
メインスレッドは、永久に実行されるべき子スレッド (クロック) を開始します。

10 秒待って、 時計に終了の合図を送ります。

メインスレッドは作業を完了します。

クロック スレッドは作業を終了します。

「スレッドが複数ある場合はどうなるでしょうか?」

「スレッドごとにそのような変数を用意するのが最善です。クラスに直接追加するのが最も便利です。そこにブール値の isRun変数を追加することもできます。ただし、タスクが次の場合にtrueになるブール値のisCancel変数を追加することをお勧めします。キャンセル。"

コード 説明
class Clock implements Runnable
{
private boolean isCancel = false;

public void cancel()
{
this.isCancel = true;
}

public void run()
{
while (!isCancel)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
Clock クラスは、 isCancel がfalseである限り、単語 «Tick» を 1 秒に 1 回コンソールに書き込みます。

isCancel がtrue になると、run メソッドは終了します。

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clock.cancel();
}
メインスレッドは、永久に実行されるべき子スレッド (クロック) を開始します。

10 秒待ってから、 cancel メソッドを呼び出してタスクをキャンセルします。

メインスレッドは作業を完了します。

クロック スレッドは作業を終了します。

「このことは心に留めておきます。ありがとう、エリー。」