実行中のスレッドを停止するにはどうすればいいですか?


実行中のスレッドを停止するにはどうすればいいですか?この面接でよく聞かれる質問には、stop()とinterrupt()の2つの方法がありますが、stop()は暴力的すぎて、スレッドビジネスの原子性を保証できず、期限が切れているので、お勧めしません.
stop()を使用してスレッドを停止
stop()メソッドは、スレッドを直ちに停止させ、このような暴力的な停止は、スレッドビジネスの原子性を破壊する可能性があります.以下に示します.
static class MyThread extends Thread {
	@Override
	public void run() {
		while (true) {
			System.out.println(" ...");
			System.out.println(" 1");
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(" 2");
			System.out.println(" ...");
		}
	}
}

public static void main(String[] args) {
	MyThread thread = new MyThread();
	thread.start();

	try {
		Thread.sleep(2000);
		thread.stop();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

実行結果:
 ...
 1

interrupt()+returnを使用してスレッドを停止
スレッド呼び出しinterrupt()は割り込みフラグを生成し、スレッドロジックにおいてisInterrupted()により割り込みフラグが存在するか否かを判断する、存在すればreturn.
static class MyThread extends Thread {
	@Override
	public void run() {
		for (int i = 0; i < 500000; i++) {
			if (this.isInterrupted()) {
				System.out.println(" ,  for .");
				return;
			}
			System.out.println("i=" + (i + 1));
		}
	}
}

public static void main(String[] args) {
	MyThread thread = new MyThread();
	thread.start();

	try {
		Thread.sleep(200);
		thread.interrupt();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

結果:…i=38319 i=38320 i=38321 iスレッドが終了し、forループが停止する.
interrupt()+InterruptedExceptionを使用してスレッドを停止
スレッド呼び出しinterrupt()は、スレッドロジックにおいてisInterrupted()によって割り込みフラグが存在するか否かを判定する割り込みフラグを生成し、存在する場合はInterruptedExceptionを放出する、同時に取り込む.
static class MyThread extends Thread {
	@Override
	public void run() {
		try {
			for (int i = 0; i < 100000; i++) {
				if (this.isInterrupted()) {
					System.out.println(" ,  for .");
					throw new InterruptedException();
				}
				System.out.println("i=" + (i + 1));
			}
		} catch (InterruptedException e) {
			System.out.println("MyThread InterruptedException.");
			e.printStackTrace();
		}
	}
}

public static void main(String[] args) {
	MyThread thread = new MyThread();
	thread.start();

	try {
		Thread.sleep(200);
		thread.interrupt();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

結果:
i=34901
i=34902
i=34903
 ,  for .
MyThread InterruptedException.
java.lang.InterruptedException
	at org.tyshawn.thread.ThreadTest$MyThread.run(ThreadTest.java:27)

interrupt()はsleep()に遭遇し、join()とwait()はInterruptedExceptionを放出します.
スレッドがブロック状態である場合、interrupt()メソッドを呼び出すとInterruptedExceptionが放出される.
	static class MyThread extends Thread {
	@Override
	public void run() {
		try {
			System.out.println(" ");
			Thread.sleep(300);
			//this.join();
			//this.wait();
			System.out.println(" ");
		} catch (InterruptedException e) {
			System.out.println("MyThread InterruptedException.");
			e.printStackTrace();
		}
	}
}

public static void main(String[] args) {
	MyThread thread = new MyThread();
	thread.start();

	try {
		Thread.sleep(200);
		thread.interrupt();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

結果:
 
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at org.tyshawn.thread.ThreadTest$MyThread.run(ThreadTest.java:56)
MyThread InterruptedException.