Javaでスレッドを停止、一時停止、再開する

概念的な知識

簡単な紹介

一時停止、再開、および停止操作のスレッドスレッドに対応するAPIは、suspend()、resume()、およびstop()です。ただし、これらのAPIは古くなっているため、お勧めしません。推奨されない主な理由は次のとおり
です。例としてsuspend()メソッドを取り上げます。呼び出し後、スレッドは占有されているリソース(ロックなど)を解放しませんが、リソースを占有してスリープ状態になり、デッドロックの問題が発生しやすくなります。
同様に、stop()メソッドは、スレッドの終了時にスレッドのリソースの通常の解放を保証しません。通常、スレッドにはリソース解放作業を完了する機会が与えられないため、プログラムは不確実な状態で動作する可能性があります。suspend()、resume()、およびstop()メソッドの副作用のため、これらのメソッドは、推奨されない期限切れのメソッドとしてマークされます。

スレッドを停止します

1.stop有効期限が切れているため、お勧めしません。停止は、非常に暴力的なLinuxの強制終了プロセスに相当します。ユーザーがまだ処理されていないリクエストを持っているかどうかはわかりません。強制的に閉じると、予期しない問題が発生する可能性があります。現れる

2.interruptエレガントな割り込み。
後続のリクエストが入らないように最初にこれを使用し、同時に現在実行中のプロセスが処理されるのを待ってからスレッドを停止することをお勧めします。

3…指示により、揮発性ブールisStop = false;

揮発性はスレッドに表示されます。

4…Thread.interrupted();

設定された割り込みフラグでスレッドをリセットすることは、interruptedをfalseに変えることです。

スレッドの中断に関連する3つの方法があります。

public void Thread.interrupt()//スレッドを中断します
public boolean Thread.isInterrupted()//中断されて
いるかどうかを判断しますpublic static boolean Thread、interrupted()//中断されているかどうかを判断し、現在の中断ステータスをクリアします

スレッドはメソッドisInterrupted()を使用して中断されているかどうかを判別するか、静的メソッドThread.interrupted()を呼び出して現在のスレッドが中断されているかどうかを判別できますが、Thread.interrupted()は割り込みフラグをfalseに書き換えます。

isInterrupted()メソッドはブール型であり、スレッドが中断された場合はtrueを返し、それ以外の場合はfalseを返します。

スレッドがブロッキング状態にある場合(thread.sleep、thread.join、thread.waitなどを呼び出すスレッドなど)、スレッドが割り込みフラグをチェックしている場合、割り込みフラグがtrueであることが判明すると、これらのブロッキングメソッド呼び出しでスローされます。 InterruptedException例外がスローされ、スレッドの割り込みフラグビットは、例外がスローされた直後にクリアされます。つまり、falseにリセットされます。

スレッドを停止するためにキャンセルフラグをカスタマイズすることはお勧めしません。runメソッドにブロッキング呼び出しがあるため、キャンセルフラグをすばやく検出することはできず、キャンセルフラグをチェックする前に、スレッドはブロッキング呼び出しから戻る必要があります。この場合、割り込みを使用することをお勧めします。

第一に、スリープなどの一般的なブロッキング方法は割り込みチェックをサポートします。
第二に、割り込みビットのステータスのチェックとキャンセルフラグのチェックに違いはありません。割り込みビットのステータスを使用すると、キャンセルフラグの宣言を回避し、リソース消費を削減することもできます。
注:デッドロック状態のスレッドは中断できません

スレッドを中断するケース中断方法

スレッドスレッドの中断

1秒後にスレッドを中断します
。mainメソッドを実行して、コンソールの印刷とタイムスタンプを表示します。1000ミリ秒(1秒)後にスレッドが中断されていることがわかります。


import utils.SleepTools;

public class UseThread extends Thread {
    
    
	public UseThread(String name) {
    
    
		super(name);
	}

	@Override
	public void run() {
    
    
		String threadName = Thread.currentThread().getName();
		while (!isInterrupted()) {
    
    //检查当前线程是否被中断(平时开发用这个就行了)

			System.out.print(threadName + " 正在运行    ,");
			System.out.println(threadName + "内部interrrupt标记 = "
					+ isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());

		}

		//建议在下面的输出语句打断点,更好的查看效果
		System.out.print("线程将要停止了,   ");
		System.out.println(threadName + " interrrupt标记 =" + isInterrupted()+ "  当前系统时间戳是" + System.currentTimeMillis() );//变成true就是中断了
	}

	public static void main(String[] args) {
    
    
		UseThread thread = new UseThread("线程1");
		thread.start();
		SleepTools.second(1);//睡眠一秒
		thread.interrupt();//中断线程,其实设置线程的标识位true

	}
}

実行可能なスレッドを中断する

1秒後にスレッドを中断します
。mainメソッドを実行して、コンソールの印刷とタイムスタンプを表示します。1000ミリ秒(1秒)後にスレッドが中断されていることがわかります。


import utils.SleepTools;

public class UseRunnable implements Runnable {
    
    
	@Override
	public void run() {
    
    
//		boolean interrupted = Thread.currentThread().isInterrupted(); 主要这么写,中断线程无效
//		while (!interrupted) {// 不要这么写,中断线程无效

		while (!Thread.currentThread().isInterrupted()) {
    
    
			System.out.println(Thread.currentThread().getName()
					+ "我是实现Runnable的线程,此时的interrupt标记位是 "
					+ Thread.currentThread().isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());
		}

		System.out.println(Thread.currentThread().getName() + "interrupt 标记 是" +
				Thread.currentThread().isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());
	}


	public static void main(String[] args) {
    
    
		UseRunnable useRunnable = new UseRunnable();
		Thread thread = new Thread(useRunnable, "Runnable线程");
		thread.start();

		SleepTools.second(1);//睡眠一秒

//		Thread.currentThread().interrupt(); 这样中断线程是无效的,不要这么写

		thread.interrupt(); //设置中断线程

	}
}


異常に中断されたスレッド

例外を送信する場合にスレッドを中断する場合は、catchコードブロックでThread.currentThread()。interrupt()を使用してください。
これを行わないと、特定の結果が発生します。特定の結果については、次のコードを実行して効果を確認してください。



import utils.SleepTools;

public class UseRunnable implements Runnable {
    
    
	@Override
	public void run() {
    
    
//		boolean interrupted = Thread.currentThread().isInterrupted(); 主要这么写,中断线程无效
//		while (!interrupted) {// 不要这么写,中断线程无效

		while (!Thread.currentThread().isInterrupted()) {
    
    
			try {
    
    

				System.out.println(Thread.currentThread().getName() + "我是实现Runnable的线程,此时的interrupt标记位是 " + Thread.currentThread().isInterrupted());
				int a = 1 / 0;
			} catch (Exception e) {
    
    
				/*需要在catch里面手动中断一下,如果想知道不这样写的后果,
				可以注释这个代码试试  , 然后仔细观察控制台打印输出语句.,*/
//				Thread.currentThread().interrupt();
				e.printStackTrace();
			}


		}

		System.out.println(Thread.currentThread().getName() + "interrupt 标记 是" +
				Thread.currentThread().isInterrupted());
	}


	public static void main(String[] args) {
    
    
		UseRunnable useRunnable = new UseRunnable();
		Thread thread = new Thread(useRunnable, "Runnable线程");
		thread.start();

		SleepTools.second(1);//睡眠一秒

//		Thread.currentThread().interrupt(); 这样中断线程是无效的,不要这么写

		thread.interrupt(); //设置中断线程

	}
}


おすすめ

転載: blog.csdn.net/qq_41489540/article/details/109109945