【インタビュー】Java並行性(1)

0.質問の概要

1.コンセプトとツール

1、进程和线程
 - 追问1:Java线程有几种状态?

2、什么是线程安全,怎么保证多线程线程安全?(*43、线程的局部变量
 - 追问1:为什么安全?
 - 追问2:如何跨越方法边界呢?

4、什么情况下Java程序会产生死锁?(*2)如何定位、修复?(*2)【第18讲】(死锁处理办法)
 - 追问1:Java调试命令。看线程运行状态用什么?看堆栈信息用什么?

5、如何终止一个正在运行的线程?
 - 追问1:如何优雅终止线程池?

1.コンセプトとツール

1.プロセスとスレッド

プロセスは最小のリソース割り当て単位であり、スレッドは最小の実行単位です。スレッドは、同じプロセスのメモリスペースと他のリソースを共有しますプロセスの下に1つ以上のスレッドが存在する可能性があり、各スレッドには独立したレジスタとスタックのセットがあり、スレッド制御フローが比較的独立していることを保証します。
1

补充:
1、协程是为了避免线程IO阻塞,能去做其他事情,因此把程序逻辑封装在叫协程的抽象里。
フォローアップ1:Javaスレッドにはいくつの状態がありますか?

2

フォローアップ2:スレッドが待機している領域について、詳細に話します

……(とりあえずわからない)

2.スレッドセーフとは何ですか?マルチスレッドスレッドセーフを確保する方法は?(* 4)

スレッドセーフ:異なるスレッドがエラーや予測できない結果なしに同じリソースにアクセスします。

保証方法:同期、揮発性、並行ツール、再入可能ロックなど。

補足:

コンテンツ 明確な
同時コレクション java.util.concurrent包 ConcurrentHashMap()
原子オブジェクト AtomicInteger、AtomicLong、AtomicXXX……
同期方法 同期された変更されたメソッド/ステートメント 同期されたキーワード
揮発性 スレッド間の可視性の問題を解決し、JVMがCPUキャッシュではなくメインメモリを読み書きするようにします。 揮発性の修正変数
リエントラントロック 改善されたロックの実装 ReentrantLock
読み取り/書き込みロック 書き込むスレッドがない場合、リソースを読み取るスレッドが多数存在する可能性があります。そうしないと、他のスレッドがリソースを取得できなくなります。 ReadWriteLock
ステートレスな実現
不変の実装
スレッドローカル変数 フィールドはローカライズされており、スレッド間で共有されません
同期コレクション Collections.synchronizedCollection()
外部ロック

……

3.ローカル変数をスレッド化します

ローカル変数:メソッド内の変数。

//生成斐波那契数列
public int[] fibonacci(int n){
    
    
    //存放结果的数组
    int[] result = new int[n];
    //数组的第1项和第2项为1
    result[0] = result[1] = 1;
    //计算第3项到第n项
    for(int i = 2; i < n; i++){
    
    
        result[i] = result[i-2] + result[i-1];
    }
    return result;  // 调用result生成斐波那契数列,result是安全的
}

データの競合は発生せず、スレッドセーフです。

フォローアップ1:なぜ安全なのですか?

ローカル変数は呼び出しスタックに格納されます。スタックフレームは、メソッドが呼び出されたときに作成され、メソッドが戻ったときに破棄されます。
4
各スレッドには独自の独立した呼び出しスタックがあるため、同時実行の問題はありません。
5

フォローアップ2:メソッドの境界を越える方法は?

変数はヒープ内に作成する必要があります。

4. Javaプログラムはどのような状況でデッドロックしますか?(* 2)見つけて修理する方法は?(* 2)【レクチャー18】(デッドロック処理方法)

デッドロックは特定のプログラム状態です。エンティティ間では、循環依存のため、エンティティは常に相互に待機しており、個人が先に進むことはできません。デッドロックは、スレッド間だけでなく、排他的リソースを持つプロセス間でも発生します。一般的に言えば、マルチスレッドシナリオでのデッドロックに主に焦点を当てています。つまり、2つ以上のスレッドは、互いのロックを保持しているため、永続的にブロックされます。

次のサンプル図を使用して、基本的なデッドロックの問題を理解できます。
9

デッドロックを見つける最も一般的な方法は、jstackなどのツールを使用してスレッドスタックを取得し、相互の依存関係を見つけてから、デッドロックを見つけることです。より明白なデッドロックである場合、JConsoleと同様に、多くの場合jstackなどを直接見つけることができ、グラフィカルインターフェイスで限定的なデッドロック検出を実行することもできます。

プログラムの実行中にデッドロックが発生した場合、ほとんどの場合、オンラインで解決することはできません。プログラム自体の問題を再起動して修正することしかできません。したがって、コード開発フェーズで相互に確認したり、予防的な調査のためのツールを使用したりすることが重要な場合がよくあります。

フォローアップ1:Javaデバッグコマンド。スレッドの実行ステータスは何ですか?スタック情報を表示するために何が使用されますか?

……

5.実行中のスレッドを終了するにはどうすればよいですか?

stop():刀を使って喉を封じると、終結した糸が葬式の面倒を見る機会がないので、使用はお勧めしません。
Interrupt():スリープ状態のスレッドをRUNNAVBLE状態に変換し、割り込みビットを設定してから、中止するかどうかを決定できます。
..。

フォローアップ1:スレッドプールを正常に終了する方法は?

メソッド:shutdown()およびshutdownNow()
shutdown():控えめで、実行後、新しいタスクは受信されませんが、実行中およびブロック中のタスクの実行が完了するのを待ってから、最終的にシャットダウンします。
shutdownNow():急進的で、新しいタスクを拒否し、実行中のタスクを強制的に停止し、同時にキューをブロックします。正常な終了には、スレッドの中断を正しく処理する必要があります。

2、参照

1.プログラマは、プロセスとスレッドについて明確でなければならない
2. Kotlinのコルーチンの練習でプロセス、スレッド、コルーチン
3.プロセス、スレッド、およびコルーチンはまだ区別できていますか?P7大物は方言で、あなたは数秒で直接理解することができますについて説明します。
4、09 | Javaのスレッド(その1):Javaのスレッドのライフサイクル
5.スレッドの安全性とは何ですか?達成する方法は?
6. [高い同時実行性]インタビュアーは私に尋ねました:なぜローカル変数はスレッドセーフなのですか?
7. 35 | 2段階終了モード:スレッドを正常に終了するにはどうすればよいですか?

おすすめ

転載: blog.csdn.net/HeavenDan/article/details/112613534