要約する
- 本「Linux Shell Scripting Raiders」の第 3 章 (83/268) を学習しました。
- 「The Art of JAVA Concurrent Programming」という本を読んで学習を始めましょう
jstack
デッドロックの状況を確認するvolatile
CPU 命令セットの処理ロジックについての一般的な理解がある
明日の手配
- 「The Art of JAVA Concurrent Programming」という本を読み続けてください。
メモの内容
「JAVA同時プログラミングの芸術」
- コンテキストスイッチを減らすにはどうすればよいでしょうか?
- ロックフリーの同時プログラミング。複数のスレッドがロックを競合するとコンテキストスイッチが発生するため、複数のスレッドでデータを処理する場合には、データのIDをハッシュアルゴリズムで分割し、異なるスレッドで処理するなど、ロックの使用を回避する方法が考えられます。データのさまざまなセグメントを処理します。
- CAS アルゴリズム。Java の Atomic パッケージは、CAS アルゴリズムを使用して、ロックせずにデータを更新します。
- 最小限のスレッドを使用します。不要なスレッドの作成を避けてください。たとえば、タスクはほとんどありませんが、処理のために多くのスレッドが作成され、多数の郡が待機状態になります。
戦闘
コマンドを使用してjstack
process 内に多数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.20
、1.18.10
そのバージョンはどこから来たのでしょうか?
ファイルを再度確認するとpom.xml
、サブプロジェクトがpom.xml
下位バージョンを導入していることがわかります。
サブプロジェクトが参照を削除し、問題が解決されました