難しすぎる!インタビュアーは実際に実行中のスレッドを停止することを望んでいますか?

スレッドを停止するということは、タスクがタスクの処理を完了する前に実行されている操作を停止すること、つまり現在の操作を放棄することを意味します。Thread.stop()メソッドを使用してスレッドを停止できますが、使用しないことをお勧めします。実際に実行中のスレッドを停止することはできますが、このメソッドは安全ではなく、非推奨になっています。

Javaで実行中のスレッドを終了する方法は3つあります。

終了フラグを使用して、スレッドを正常に終了させます。つまり、runメソッドが完了するとスレッドが終了します。
強制終了にはstopメソッドを使用しますが、一時停止や再開などのstopは期限切れのメソッドであるため、このメソッドはお勧めしません。
スレッドを中断するには、interruptメソッドを使用します。

止められない糸

interrupt()メソッドの効果は、ループを即座に停止するfor + breakステートメントとは異なります。割り込みメソッドの呼び出しは、現在のスレッドで一時停止の標識を押すことであり、実際にはスレッドを停止することではありません。ここに写真の説明を挿入
出力結果:ここに写真の説明を挿入

スレッドが停止しているかどうかを確認します

「2020年の最新のJavaの基本と詳細なビデオチュートリアルおよび学習ルート!"
Thread.javaクラスには、次の2つのメソッドがあります。

this.interrupted():現在のスレッドが中断された
かどうかをテストします; this.isInterrupted():スレッドが中断されたかどうかをテストします;では
、これら2つのメソッドの違いは何ですか?

this.interrupted()メソッドの説明を見てみましょう。現在のスレッドが中断されているかどうかをテストします。現在のスレッドはthis.interrupted()メソッドを実行しているスレッドを参照しています。
ここに写真の説明を挿入
演算結果:

??
 ??
复制代码

クラスRun.javaは、スレッドオブジェクトで次のコードを呼び出しますが、thread.interrupt()。これは後で使用されます。

(" 1??" + ());
(" 2??" + ());
复制代码

スレッドオブジェクトで表されるスレッドが停止しているかどうかを判断するために、コンソールに出力された結果から、スレッドは停止していません。これは、現在のスレッドが中断されているかどうかをテストするinterrupted()メソッドの説明でもあります。この現在のスレッドはメインであり、中断されたことがないため、出力結果は2つのfalseになります。

メインスレッドに割り込み効果を生成させる方法は?
ここに写真の説明を挿入
実行中の効果は次のとおりです。

??
 ??
复制代码

メソッドinterrupted()は、現在のスレッドが停止しているかどうかを判別します。しかし、なぜ2番目のブール値がfalseなのですか?公式ヘルプドキュメントでの中断されたメソッドの説明:

現在のスレッドが中断されているかどうかをテストします。スレッドの割り込みステータスは、このメソッドによってクリアされます。

つまり、メソッドが2回続けて呼び出された場合、2回目の呼び出しはfalseを返します。

inInterrupted()メソッドを見てみましょう。

ここに写真の説明を挿入
動作結果:

??
??
コード
isInterrupted()をコピーして状態をクリアすると、2つのtrueが出力されます。

停止できるスレッド-例外メソッド

以前に学習した知識ポイントを使用して、スレッドでforステートメントを使用して、スレッドが停止状態にあるかどうかを判断できます。スレッドが停止状態にある場合、次のコードは実行できなくなります。
ここに写真の説明を挿入
操作結果:ここに写真の説明を挿入

上記の例ではスレッドを停止していますが、forステートメントの下にステートメントがある場合は、引き続き実行されます。次の例を見てくださいここに写真の説明を挿入
。Run.javaを使用した結果は次のとおりここに写真の説明を挿入
です。ステートメントの実行を継続する問題を解決するにはどうすればよいですか。更新されたコードを見てください
ここに写真の説明を挿入
。Run.javaを使用した結果は次のとおりです。

ここに写真の説明を挿入
深い眠りで止まる

スレッドがsleep()状態でスレッドを停止した場合の影響は何ですか?ここに写真の説明を挿入
Run.javaで実行した結果は、次のとおりです。出力ここに写真の説明を挿入
された結果から、スレッドがスリープ状態で停止した場合、スレッドはcatchステートメントに入り、停止状態の値をクリアしてfalseにします。

前の実験では、最初にスリープしてから、interrupt()を使用して停止しました。学習プロセスでは、反対の操作に注意する必要があります。

ここに写真の説明を挿入
実行結果:ここに写真の説明を挿入
停止可能なスレッド-ブルートフォース停止

stop()メソッドを使用してスレッドを停止することは非常に暴力的です。ここに写真の説明を挿入
操作結果:ここに写真の説明を挿入
6。メソッドstop()およびjava.lang.ThreadDeath例外
stop()メソッドを呼び出すと、java.lang.ThreadDeath例外がスローされますが、通常、この例外を明示的にキャプチャする必要はありません。

ここに写真の説明を挿入
スレッドを強制的に停止すると、一部のクリーンアップ作業が完了しない可能性があるため、stop()メソッドは廃止されました。もう1つの状況は、ロックされたオブジェクトのロックが解除されてデータが同期されなくなり、データの不整合の問題が発生することです。

ロックを解除した場合の望ましくない結果

stop()を使用してロックを解放すると、データの不整合が発生します。このような状況が発生した場合、プログラムによって処理されたデータが破壊され、最終的にプログラムの実行プロセスでエラーが発生する可能性があります。特に注意する必要があります。

public class SynchronizedObject {
    
        private String name = "a";    private String password = "aa";    public synchronized void printString(String name, String password){
    
            try {
    
                this.name = name;            Thread.sleep(100000);            this.password = password;        } catch (InterruptedException e) {
    
                e.printStackTrace();        }    }    public String getName() {
    
            return name;    }    public void setName(String name) {
    
            this.name = name;    }    public String getPassword() {
    
            return password;    }    public void setPassword(String password) {
    
            this.password = password;    }}public class MyThread extends Thread {
    
        private SynchronizedObject synchronizedObject;    public MyThread(SynchronizedObject synchronizedObject){
    
            this.synchronizedObject = synchronizedObject;    }    public void run(){
    
            synchronizedObject.printString("b", "bb");    }}public class Run {
    
        public static void main(String args[]) throws InterruptedException {
    
            SynchronizedObject synchronizedObject = new SynchronizedObject();        Thread thread = new MyThread(synchronizedObject);        thread.start();        Thread.sleep(500);        thread.stop();        System.out.println(synchronizedObject.getName() + "  " + synchronizedObject.getPassword());    }}
复制代码

出力結果:

b  aa
复制代码

stop()メソッドとJDKで「期限切れ/廃止」とマークされたメソッドは明らかに機能上の欠陥があるため、プログラムでstop()メソッドを使用することはお勧めしません。

returnを使用してスレッドを停止します

returnと組み合わせたメソッドinterrupt()は、スレッドを停止する効果も実現できます。

public class MyThread extends Thread {
    
        public void run(){
    
            while (true){
    
                if(this.isInterrupted()){
    
                    System.out.println("线程被停止了!");                return;            }            System.out.println("Time: " + System.currentTimeMillis());        }    }}public class Run {
    
        public static void main(String args[]) throws InterruptedException {
    
            Thread thread = new MyThread();        thread.start();        Thread.sleep(2000);        thread.interrupt();    }}
复制代码

出力結果:

...Time: 1467072288503Time: 1467072288503Time: 1467072288503线程被停止了!
复制代码

ただし、スレッド停止イベントを伝播できるように例外をcatchブロックにスローすることもできるため、「例外のスロー」メソッドを使用してスレッドを停止することをお勧めします。

元のリンク:https://juejin.cn/post/6906365708230197261

おすすめ

転載: blog.csdn.net/weixin_46699878/article/details/111215939