2021-04-26 jstack を使用してシミュレートされたデッドロックを表示する

要約する

  • 本「Linux Shell Scripting Raiders」の第 3 章 (83/268) を学習しました。
  • 「The Art of JAVA Concurrent Programming」という本を読んで学習を始めましょう
  • jstackデッドロックの状況を確認する
  • volatileCPU 命令セットの処理ロジックについての一般的な理解がある

明日の手配

  • 「The Art of JAVA Concurrent Programming」という本を読み続けてください。

メモの内容

「JAVA同時プログラミングの芸術」

  • コンテキストスイッチを減らすにはどうすればよいでしょうか?
    • ロックフリーの同時プログラミング複数のスレッドがロックを競合するとコンテキストスイッチが発生するため、複数のスレッドでデータを処理する場合には、データのIDをハッシュアルゴリズムで分割し、異なるスレッドで処理するなど、ロックの使用を回避する方法が考えられます。データのさまざまなセグメントを処理します。
    • CAS アルゴリズムJava の Atomic パッケージは、CAS アルゴリズムを使用して、ロックせずにデータを更新します。
    • 最小限のスレッドを使用します不要なスレッドの作成を避けてください。たとえば、タスクはほとんどありませんが、処理のために多くのスレッドが作成され、多数の郡が待機状態になります。

戦闘

コマンドを使用してjstackprocess 内に多数WAITINGのプロセスがあるかどうかを確認し、
スレッド プールのサイズが適切であるかどうかを判断します。アイドル状態のスレッドの数を減らすことで、コンテキストの切り替えの数を減らします。

シミュレートされたデッドロック

シミュレーションコードは次のとおりです


public class 模拟死锁 {
    
    
    private final static String A = "A";
    private final static String B = "B";

    @Test
    public void test() throws InterruptedException {
    
    
        Thread threadA = new Thread(()->{
    
    
            synchronized(A){
    
    
                try {
    
    
                    Thread.sleep(100);
                    synchronized (B){
    
    
                        System.out.println("Get");
                    }
                } catch (InterruptedException e) {
    
     }
            }
        });
        Thread threadB = new Thread(()->{
    
    
            synchronized(B){
    
    
                try {
    
    
                    Thread.sleep(100);
                    synchronized (A){
    
    
                        System.out.println("Get");
                    }
                } catch (InterruptedException e) {
    
     }
            }
        });
        threadA.start();
        threadB.start();
        threadA.join();
        System.out.println("END");
    }
}

を使用しますjstack。出力結果にはデッドロックに関するプロンプト メッセージがすでに存在します。

virde@virde : ~ $ jps -l
76342 org.jetbrains.jps.cmdline.Launcher
76424 jdk.jcmd/sun.tools.jps.Jps
67466 com.intellij.idea.Main
76364 com.intellij.rt.junit.JUnitStarter
76126 org.jetbrains.idea.maven.server.RemoteMavenServer36
67934 org.jetbrains.idea.maven.server.RemoteMavenServer36 virde@virde : ~ $ jstack 76364
2021-04-26 15:43:08
フル スレッド ダンプ Java HotSpot(TM) 64 -ビット サーバー VM (25.181-b13 混合モード):
上記のスレッドの Java スタック情報:
……
……
========================= ==========================
「スレッド-1」:


	マルチスレッド時。シミュレートされたデッドロック.lambda$test$1(シミュレートされたデッドロック.java :26)
	- <0x000000076d73f678> (java.lang.String) をロックするのを待機しています-
	マルチスレッドで
	<0x000000076d73f6a8> (java.lang.String) をロックしています
	。java.lang でデッドロック $$Lambda$2/380894366.run(Unknown Source) をシミュレートします。 Thread.run(Thread.java:748) 
"Thread-0":
	マルチスレッド時。Simulated Deadlock.lambda$test$0(Simulated Deadlock.java:16) 
	- <0x000000076d73f6a8> (java.lang.String) をロックするのを待機しています
	- locked <0x000000076d73f678> (a java.lang.String) 
	at multithreading. デッドロック $$Lambda$1/1068824137.run(Unknown Source) 
	at java.lang.Thread.run(Thread.java:748 ) をシミュレートし
ます デッドロックが 1 つ見つかりました。virde@バード: ~ $


デッドロックを回避するためのいくつかの一般的な方法

  • 1 つのスレッドが同時に複数のロックを取得しないようにする
  • スレッドがロック内の複数のリソースを同時に占有することを避け、各ロックが 1 つのリソースのみを占有するようにしてください。
  • lock.tryLock(timeout)内部ロック機構を使用する代わりに、時限ロックを使用してみてください。
  • データベース ロックの場合、ロックとロック解除は 1 つのデータベース接続内で行う必要があります。そうでない場合、ロック解除は失敗します。

IDEAlombokエラー解決記録

プロジェクトで使用されlombok、mvn のビルド時にエラーは報告されませんでしたが、実行時にエラーが報告されました。
get メソッドと set メソッドが見つかりません。

Baidu は、Maven バージョンが idea lombok バージョンと矛盾している場合、エラーが報告される可能性があることを知りました。
ルート ディレクトリpom.xmlにある最新バージョンに更新されますlombokまだエラーが発生します。

External Librariesプロジェクトのディレクトリ内のファイルを確認すると、
次の 2 つのバージョンがあることがわかります。lombok

Maven:org.projectlombok:lombok:1.18.10
Maven:org.projectlombok:lombok:1.18.20

もちろん最新バージョンを導入しましたが1.18.201.18.10そのバージョンはどこから来たのでしょうか?
ファイルを再度確認するとpom.xml、サブプロジェクトがpom.xml下位バージョンを導入していることがわかります。

サブプロジェクトが参照を削除し、問題が解決されました

参考: idea lombok の概要とレッド レポートとエラー レポートの解決策

おすすめ

転載: blog.csdn.net/kaka_buka/article/details/116170678