- PR -

デッドロック

1
投稿者投稿内容
space-girl
会議室デビュー日: 2005/08/19
投稿数: 3
投稿日時: 2005-08-19 16:25
下記のサンプルはデッドロックを起こすソースなのですが、
public class Deadlock extends Thread {
public static Object l1 = new Object();
public static Object l2 = new Object();
private int index;
public static void main(String[] a) {
Thread t1 = new ThreadA();
Thread t2 = new ThreadB();
t1.start();
t2.start();
}

private static class ThreadA extends Thread {
public void run() {
synchronized (l1) {
System.out.println("スレッド1: l1に対するロックを取得");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("スレッド1: l2のロックの開放待ち");
synchronized (l2) {
System.out.println("スレッド1: l1、l2に対するロックを取得");
}
}
}
}

private static class ThreadB extends Thread {
public void run() {
synchronized (l2) {
System.out.println("スレッド2: l2に対するロックを取得");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("スレッド2: l1のロックの開放待ち");
synchronized (l1) {
System.out.println("スレッド1: l1、l2に対するロックを取得");
}
}
}
}
}



これを元に、
Junitでデッドロックを起こすサンプルをつくりたいと思っています。
ControllableTestThread
MultithreadedTestCase
のクラスを使って作成しようと思っているのですが
高度なクラス(マイナー??)みたいで、サイトを検索しても
ほとんど参考になるサイトがでてきません。
どなたか、よいアドバイスをいただけますでしょうか?
環境は
eclipse3.0
jre1.4
tomcat4.1
です。
とても困っています。よろしくお願いします。


あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2005-08-19 17:18
何を質問したいのか伝わりませんが、
JUnitでデッドロックを起こしたという理由は何なんでしょうか。
単にUnit Testをデッドロックで妨害させたいわけではないですよね?

#デッドロック検出機構のテストをしたい、等でしょうか?

それと、例示されたコードは「デッドロックを必ず起こす」コードではなく、
「デッドロックを起こす可能性のある(高い)」コードではないでしょうか。
両スレッドの間で開始を同期化していないめ、タイミングの仮定ができず、
ThreadAの完了までThreadBが開始されない可能性すらありえてしまいます。
Sleep(10)を行っているため、可能性といっても低いとは思いますが。

確実にデッドロックさせたいのであれば、wait()/notify()やCyclicBarrier
などで状況をお互いに通知しあい、期待した順序通りに実行できるように
制御する必要があると思います。
space-girl
会議室デビュー日: 2005/08/19
投稿数: 3
投稿日時: 2005-08-19 18:17
回答ありがとうございます。

私自身よくわかっていない事だらけで、
質問の内容があやふやになり申し訳ございません。

妨害ではありません。
サンプルを作ってデッドロックが起きるテストの検証に使うため
作りたいです。
(サンプルのテストを実行してデッドロックが実際に起こるか
確認するためです。)

こちらのサンプルコードでは、
デッドロックの可能性が低いのですね。
がんばって改良してみます。


また、今まで
MultithreadedTestCase について調べたのですが、
クラス説明についていたサンプルなのですが、
public void test() {
TestThread t1 = new TestThread("1", "value");
TestThread t2 = new TestThread("2", "value");

ControllableTestThread[] threads = new ControllableTestThread[] {t1, t2};
int secondsToRun = 5;

startAndWait(threads, secondsToRun);

printStats("TestThreads (a message)", threads, secondsToRun);
assertTrue(t1.getFailures() == 0);
assertTrue(t2.getFailures() == 0);
}


TestThread でエラーになってしまいます。
これは、
ControllableTestThreadクラスを継承するクラスを
自分で作成するということなのでしょうか。
自分で調べてはいるのですが、
ControllableTestThread
MultithreadedTestCase
クラスのメソッドの使い方がわからず、実装方法も不明で
・・・
情報が少なくて困っています。
こちらのクラスについて知っている方がいらっしゃいましたら
教えていただきたいです。よろしくお願いします。

山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-08-19 22:30
とりあえず、デッドロックをほぼ確実に発生させるサンプルです
コード:
public class StackSample{
    public static void main(String args[]){
        Object obj1 = new Object();
        Object obj2 = new Object();
        Thread athred1 = new AThread(obj1,obj2);
        Thread athred2 = new AThread(obj2,obj1);
        athred1.start();
        athred2.start();
    }
}
class AThread extends Thread{
    Object lock1;
    Object lock2;
  public AThread(Object arg1,Object arg2){
      lock1 = arg1;
      lock2 = arg2;
  }
  public void run(){
      while(true){
          try{
              synchronized (lock1) {
                  Thread.sleep(10);
                  synchronized (lock2) {
                      Thread.sleep(10);
                  }
              }
          }catch(InterruptedException ignore){}
      }

  }
}

あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2005-08-19 23:31
引用:
ControllableTestThread
MultithreadedTestCase
クラスのメソッドの使い方がわからず、実装方法も不明で



これらが何のクラスで何に含まれるのかわかりませんが、
デッドロックをさせたいというよりは、マルチスレッドなアプリケーション
向けにいろいろな実行状況を作り出すためのテストケースなんでしょうね。

↓のは確実にデッドロックを発生させるコードです。
もう少し簡略化できるかもしれませんが。。

public class Deadlock extends Thread {

  private static Object trigger = new Object();
  private Object l1;
  private Object l2;

  public Deadlock(Object l1, Object l2) {
    this.l1 = l1;
    this.l2 = l2;
  }

  public void run() {
    try {
      System.out.println(this + ": ロック(" + l1 + ")獲得開始");
      synchronized (l1) {
        System.out.println(this + ": ロック(" + l1 + ")獲得完了");
        synchronized (trigger) {
          synchronized (this) {
            notify();
          }
          trigger.wait();
        }
        System.out.println(this + ": ロック(" + l2 + ")獲得開始");
        synchronized (l2) {
          System.out.println(this + ": ロック(" + l2 + ")獲得完了");
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    try {
      Object l1 = new Object();
      Object l2 = new Object();
      Thread t[] = { new Deadlock(l1, l2), new Deadlock(l2, l1) };
      for (int i = 0; i < t.length; i++) {
        synchronized (t[i]) {
          t[i].start();
          t[i].wait();
        }
      }
      synchronized (trigger) {
        trigger.notifyAll();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}
space-girl
会議室デビュー日: 2005/08/19
投稿数: 3
投稿日時: 2005-08-22 10:00
返事が遅れてしまってすみませんでした。
インギさん。あしゅさん。
お力を貸していただき、ありがとうございます。
とても、たすかりました。
今日、サンプルとしてソースコードを使わせていただきます。
m(_ _)mありがとうございます。

ControllableTestThread
MultithreadedTestCase
クラスに関してなのですが、
どうやら、
複数のスレッドをテストした際に、指定した時間の間
異常なステータスが発生していないかどうかを調べるための
フレームワークのようです。

お騒がせしてすみませんでした。


1

スキルアップ/キャリアアップ(JOB@IT)