Javaのデッドロック解析


コンカレントプログラムを作成するとき、デッドロックの問題は直面し、注意し、解消しなければならない.
 
デッドロックとは
 
Wikiの解釈は、「プロセスデッドロックとは、コンピュータ技術の名詞である.オペレーティングシステムまたはソフトウェアが動作する状態である.マルチワークシステムでは、1つまたは複数のプロセスがシステムリソースを待機し、システムリソースが同時にこのプロセス本体または他のプロセスに占有されると、デッドロックが形成される」というものである.
 
例えば、スレッド1がリソースAをロックし、リソースBにアクセスしようとすると、スレッド2がリソースBをロックし、リソースAにアクセスしようとすると、スレッド1と2はいずれも相手が必要とするリソースをロックし、相手が持っているリソースが解放されるのを待ってから自分の持っているリソースを解放し続けることができ、デッドロックが発生し、両方のスレッドはリソースを待つためにブロックされ、このような相互待ちを解除する手段がなければ,理論的には両者とも永遠に待っていることが想像できる.
この現象は次のように説明できます.
 
Thread 1 locks A,waits for B
Thread 2 locks B,wats for A
次にjavaコードを示します.
 
public class TreeNode {

    TreeNode parent = null;
    List children = new ArrayList();

    public synchronized void addChild(TreeNode child) {
        if (!this.children.contains(child)) {
            this.children.add(child);
            child.setParentOnly(this);
        }
    }

    public synchronized void addChildOnly(TreeNode child) {
        if (!this.children.contains(child)) {
            this.children.add(child);
        }
    }

    public synchronized void setParent(TreeNode parent) {
        this.parent = parent;
        parent.addChildOnly(this);
    }

    public synchronized void setParentOnly(TreeNode parent) {
        this.parent = parent;
    }
}
 
 
 
TreeNodeインスタンスが2つある場合:child,parent.スレッド(1)がparentを呼び出すと.addChild(child)は、スレッド(2)がchildを呼び出す.setParent(parent).スレッド(1)ではparentオブジェクトをロックし,スレッド(2)はchildオブジェクトを同時にロックした.このとき、スレッド(1)はchildを要求しようとする、childオブジェクトのロックを取得しようとするが、このロックはスレッド(2)に保持されているため、スレッド(1)は待機をブロックせざるを得ず、スレッド(2)がparentに実行する.addChildOnly(this)の時、彼はparentの鍵を手に入れようとしたが、残念なことに、この鍵はparentに占拠され、彼も待機をブロックせざるを得なかった.こうしてカップが発生し,スレッド(1)とスレッド(2)がブロックされて待機する.
 
より複雑なデッドロック現象
 
Thead 1 locks A,waits for B,
Thead 2 locks B,waits for C,
Thead 3 locks C,waits for D,
Thead 4 locks D,waits for A
 
データベースのデッドロック
 
1つのトランザクションは1つのレコード(a)をロックして変更され、現在、レコード(b)を変更する必要があります.彼がレコード(b)のロックを要求すると、残念ながら、レコード(b)は別のトランザクションにロックされ、さらにたまたま、レコード(b)を持つロックを持つトランザクションはこの時点でレコード(a)のロックを要求し、デッドロックが再び発生します.次の現象を説明します.
 
Transaction 1 request 1,locks record 1 for update
Transaction 2 request 1,locks record 2 for update
Transaction 1 request 2,locks record 2 for update
Transaction 2 request 2,locks record 1 for update