ホームページ  >  記事  >  Java  >  【JAVA】デッドロックの発生と解決方法

【JAVA】デッドロックの発生と解決方法

php是最好的语言
php是最好的语言オリジナル
2018-08-06 13:44:333161ブラウズ

デッドロック分析

1. デッドロックの生成

2つのアカウント間の送金状況をシミュレートする次のコードがあります

void transfer(Account from,Account to,int money){
    from.setAmount(from.getAmount()-money);
    to.setAmount(to.getAmount()+money);
}

シングルスレッドではこのコードは間違いなく問題ありませんが、シングルスレッドでは問題がありますマルチスレッドの下で

ロックします。ロック後のコードは次のとおりです

void transfer(Account from,Account to,int money){
    synchronized(from){
        synchronized(to){
            from.setAmount(from.getAmount()-money);
            to.setAmount(to.getAmount()+money);
        }
    }
}

synchronized、つまりオブジェクトのロックです。最初の同期は from オブジェクトをロックし、2 番目の同期は to オブジェクトをロックします。

マルチスレッドの場合、複数のスレッドのうち 1 つのスレッドのみが同時にオブジェクト ロックを取得し、オブジェクト ロック内のコード セグメントを操作できます

しかし、オブジェクト ロックを追加した後、デッドロックが発生する可能性があります。

transfer(a,b,100)とtransfer(b,a,100)は同時に行われます、つまり、aがbに送金するとき、bもaに送金しています

【1】aが送金するbにお金を転送し、スレッドxがそれを取得します aのオブジェクトロックは

【2】bがaにお金を転送し、スレッドyがbのオブジェクトロックを取得します

操作【1】bのオブジェクトロックが緊急に必要です転送操作を実行するには

操作【2】aのオブジェクトが緊急に必要です転送操作はロックをロックすることによってのみ実行できます

両方のスレッドがグループ内の他のスレッドがロックを解放するのを待っており、デッドロックが発生しますこの時に発生します!

2.行き詰まりを解決するには

どのような点から始めるべきでしょうか?

【1】相互排他待ちを解除する

一般的に、プログラムの安全性のためにオブジェクトをロックする必要があるため、この状態は一般的には解除できません

【2】ホールドを解除して待機する、つまり独占的待機

すべてのリソースを一度に取得できる サンプルコードでは、fromとtoのリソースを一度に取得するのではなく、分散して取得します。

方法 1: to に短いタイムアウトを追加します。 to の取得の試行がタイムアウトしたら、最初に保持されていた from ロックをすぐに解放します

、from と to のロックの取得を再試行します。これが推奨される方法です

方法 2: このコードにグローバル ロックを追加して、from と to が同時に取得されるようにします。転送操作が完了したら、グローバル ロックを解放します。比較的安全ですが、銀行には多くの口座があり、送金操作が非常に頻繁に行われるため、この方法を使用すると、必然的にパフォーマンスが大幅に低下します

[3] 待機中のループを解消します

順番にリソースを取得し、次の手順に従ってください。アカウント ID のサイズ 移管操作では、ID が小さいアカウントが最初に移管操作を実行し、ID が大きいアカウントが後で移管操作を実行します。しかし現実には、IDをもたない、つまり秩序を持たないものもあります。このとき、それらに秩序を強制する必要があります。

【4】取り返しのつかない待ち時間を解消する

ユーザーの転送操作が失敗し、ユーザーエクスペリエンスが良くない場合の最後の手段としてタイムアウトを追加する

個人的に推奨される解決策:

ユーザーの短い待ち時間を犠牲にして、【方法1】を使用します。 2】

関連記事:

Javaにおけるデッドロックの概念と解決策

デッドロックの概念とデッドロックの条件

以上が【JAVA】デッドロックの発生と解決方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。