ホームページ  >  に質問  >  本文

java - 多线程死锁测试

package test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * Created by rhwayfun on 16-4-3.
 */
public class ThreadTest {

    private static DateFormat format = new SimpleDateFormat("HH:mm:ss");

    public synchronized void tryOther(ThreadTest other) throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " enter tryOther method at " + format.format(new Date()));      
        System.out.println(Thread.currentThread().getName() + " tryOther method is about to invoke other method at " + format.format(new Date()));
        other.other();
    }

    public synchronized void other() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " enter other method atatatatat " + format.format(new Date()));
    }

    public static void main(String[] args) throws InterruptedException {
        final ThreadTest d1 = new ThreadTest();
        final ThreadTest d2 = new ThreadTest();

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    d1.tryOther(d2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "threadA");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    d2.tryOther(d1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "threadB");

        t1.start();
        //让threadA先运行一秒
        TimeUnit.SECONDS.sleep(1);
        t2.start();

    }
}

如上,随便找的产生死锁的代码,问题:
TimeUnit.SECONDS.sleep(1);加上这行后,不存在死锁问题。sleep并不释放锁,为何这边死锁情况会消失。
输出结果为:
threadA enter tryOther method at 15:37:39
threadA tryOther method is about to invoke other method at 15:37:39
threadA enter other method atatatatat 15:37:39
threadB enter tryOther method at 15:37:40
threadB tryOther method is about to invoke other method at 15:37:40
threadB enter other method atatatatat 15:37:40

注掉这行,正常死锁。
输出结果为:
threadB enter tryOther method at 15:37:10
threadA enter tryOther method at 15:37:10
threadB tryOther method is about to invoke other method at 15:37:10
threadA tryOther method is about to invoke other method at 15:37:10

阿神阿神2742日前687

全員に返信(3)返信します

  • 大家讲道理

    大家讲道理2017-04-18 10:56:48

    スレッド A は tryOther ロックを取得しますが、まだ他のロックを取得する必要があります。
    スレッド B は tryOther ロックを取得しますが、まだ他のロックを取得する必要があります。
    A がロックを解放したばかりで、B がロックを取得している可能性があります。 tryOther ロックを解放したところです。
    この時点では、両方のスレッドが同時に他のロックを取得したいと考えていますが、この時点での解決策は、2 つのスレッドが 2 番目のロックを取得しないようにすることです。ただし、同時実行の量が多い場合、この方法でデッドロックを防ぐことはお勧めできません。

    返事
    0
  • 阿神

    阿神2017-04-18 10:56:48

    両当事者が同じロックをめぐって戦っているため、デッドロックは発生しません

    返事
    0
  • PHPz

    PHPz2017-04-18 10:56:48

    急に理由が分かり、投稿を削除するのが面倒でした。私の意見を書いてください。間違いがあれば修正して軽くスプレーしてください。 スリープがない場合、スレッド a が開始され、tryOther メソッドが完了し、ロックが解放され、他のメソッドが実行されます。 lock して tryOther メソッドを実行します
    このとき、a 他のメソッドでは、必要なリソースがスレッド b によってロックされています。tryOther を実行した後、b はリソースを取得する必要があるため、デッドロックが発生します。

    睡眠を追加した後。 a が tryOther メソッドを実行してロックを解放すると、この時点ではスレッド b は実行されず、この時点でもう一方のロックの取得に成功します。スレッド b は 2 秒後に実行されます。

    デッドロック環境はありません。

    返事
    0
  • キャンセル返事