찾다

 >  Q&A  >  본문

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

阿神阿神2804일 전722

모든 응답(3)나는 대답할 것이다

  • 大家讲道理

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

    스레드 A는 tryOther 잠금을 가져오지만 여전히 다른 잠금을 가져와야 합니다.
    스레드 B는 tryOther 잠금을 가져오지만 여전히 다른 잠금을 가져와야 합니다.
    A가 방금 가져왔을 가능성이 있습니다. 잠금을 해제했고 B는 방금 tryOther를 해제했습니다.
    지금은 모두 상대방의 잠금을 동시에 획득하려고 하기 때문에 누구도 교착 상태를 방지하는 것입니다.
    해결책은 두 스레드가 서로 교착 상태에 빠지는 것을 방지하는 것입니다. 두 번째 잠금을 동시에 잡습니다. 예
    그러나 시간을 나노초 수준으로 조정하고 여러 번 시도하면 교착 상태가 발생합니다
    교착 상태를 방지하는 것은 권장되지 않습니다. 동시성이 높습니다.

    회신하다
    0
  • 阿神

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

    두 당사자가 동일한 잠금을 위해 싸우고 있으므로 교착 상태는 없습니다

    회신하다
    0
  • PHPz

    PHPz2017-04-18 10:56:48

    갑자기 이유를 알고 너무 게을러서 글을 삭제하지 못했어요. 제 의견을 적겠습니다. 틀렸다면 자유롭게 지적해 주십시오.
    이때 스레드 a가 시작되어 tryOther 메소드를 완료하고 잠금을 해제한 후 다른 메소드를 실행합니다. 이때, b는 잠금을 획득하고 tryOther 메소드를 실행합니다.
    이때 다른 메소드에서 a가 필요로 하는 리소스는 스레드 b에 의해 잠깁니다. tryOther를 실행한 후 b는 a의 리소스를 획득해야 하므로 결과적으로 교착상태.

    수면 추가 후. a가 잠금을 해제하기 위해 tryOther 메소드를 실행하면 이때 스레드 b는 실행되지 않으며, 이때 다른 잠금은 성공적으로 획득됩니다. 스레드 b는 2초 후에 실행되며
    교착 상태 환경이 없습니다.

    회신하다
    0
  • 취소회신하다