- - PR -
デッドロック
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 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-19 17:18
何を質問したいのか伝わりませんが、
JUnitでデッドロックを起こしたという理由は何なんでしょうか。 単にUnit Testをデッドロックで妨害させたいわけではないですよね? #デッドロック検出機構のテストをしたい、等でしょうか? それと、例示されたコードは「デッドロックを必ず起こす」コードではなく、 「デッドロックを起こす可能性のある(高い)」コードではないでしょうか。 両スレッドの間で開始を同期化していないめ、タイミングの仮定ができず、 ThreadAの完了までThreadBが開始されない可能性すらありえてしまいます。 Sleep(10)を行っているため、可能性といっても低いとは思いますが。 確実にデッドロックさせたいのであれば、wait()/notify()やCyclicBarrier などで状況をお互いに通知しあい、期待した順序通りに実行できるように 制御する必要があると思います。 | ||||
|
投稿日時: 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 クラスのメソッドの使い方がわからず、実装方法も不明で ・・・ 情報が少なくて困っています。 こちらのクラスについて知っている方がいらっしゃいましたら 教えていただきたいです。よろしくお願いします。 | ||||
|
投稿日時: 2005-08-19 22:30
とりあえず、デッドロックをほぼ確実に発生させるサンプルです
| ||||
|
投稿日時: 2005-08-19 23:31
これらが何のクラスで何に含まれるのかわかりませんが、 デッドロックをさせたいというよりは、マルチスレッドなアプリケーション 向けにいろいろな実行状況を作り出すためのテストケースなんでしょうね。 ↓のは確実にデッドロックを発生させるコードです。 もう少し簡略化できるかもしれませんが。。 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(); } } } | ||||
|
投稿日時: 2005-08-22 10:00
返事が遅れてしまってすみませんでした。
インギさん。あしゅさん。 お力を貸していただき、ありがとうございます。 とても、たすかりました。 今日、サンプルとしてソースコードを使わせていただきます。 m(_ _)mありがとうございます。 ControllableTestThread MultithreadedTestCase クラスに関してなのですが、 どうやら、 複数のスレッドをテストした際に、指定した時間の間 異常なステータスが発生していないかどうかを調べるための フレームワークのようです。 お騒がせしてすみませんでした。 |
1