2009-07-19 3 views
0

java로 일부 연습 중입니다. (코드의 출처는 어디일까요?)Java deadlockprovocation

class Resource { 

    public Integer value = 42; 
} 

public class DeadLockRisk implements Runnable { 

    private Resource resourceA = new Resource(); 
    private Resource resourceB = new Resource(); 

    public void write(int a, int b) { 

     System.out.println(Thread.currentThread().getName() + " try write Lock A"); 

     synchronized(resourceA) { 

      System.out.println(Thread.currentThread().getName() + " write Lock A"); 
      System.out.println(Thread.currentThread().getName() + " try write Lock B"); 

      synchronized(resourceB) { 

       System.out.println(Thread.currentThread().getName() + " write Lock B"); 

       resourceA.value = a; 
       resourceB.value = b; 
     //sit on it! 
     //try { Thread.sleep(5000); } catch (Exception e) {} 

     System.out.println(Thread.currentThread().getName() + " release write B"); 
     } 
     System.out.println(Thread.currentThread().getName() + " release write A"); 
    } 
    } 

    public int read() { 

    Integer retVal; 
     System.out.println(Thread.currentThread().getName() + " try read Lock B"); 

     synchronized(resourceB) { 

      System.out.println(Thread.currentThread().getName() + " read Lock B"); 
      System.out.println(Thread.currentThread().getName() + " try read Lock A"); 

      synchronized(resourceA) { 

       System.out.println(Thread.currentThread().getName() + " read Lock A"); 
       retVal = resourceB.value + resourceA.value; 
     System.out.println(Thread.currentThread().getName() + " release read A"); 
      } 
     System.out.println(Thread.currentThread().getName() + " release read B"); 
     } 
    return retVal; 
    } 

    public void run() { 


    if (Thread.currentThread().getName().equals("Thread-1")) { 
     write(1,2); 
    } 

    System.out.println(read()); 
    } 

    public static void main(String[] args) { 

     Thread ta = new Thread(new DeadLockRisk()); 
     Thread tb = new Thread(new DeadLockRisk()); 
     ta.start(); tb.start(); 
    } 
} 

(javac의의 -version javac의 1.6.0_0 끝나면 uname -a 리눅스 인스 2.6.29 # 1 SMP 토 5월 16일 중부 유럽 표준시 10시 56분 17초 2009는 i686 GNU : 다음 코드와 deadlocksituation을 provocate하려고/리눅스)

얻을 (다른 상황들) 아래의 출력 : 내가 잘못보고하는 일

 
Thread-1 try write Lock A 
Thread-0 try read Lock B 
Thread-1 write Lock A  <===== 
Thread-0 read Lock B 
Thread-1 try write Lock B 
Thread-0 try read Lock A 
Thread-1 write Lock B 
Thread-0 read Lock A  <===== 
Thread-1 release write B 
Thread-0 release read A 
Thread-1 release write A 
Thread-0 release read B 
Thread-1 try read Lock B 
154 
Thread-1 read Lock B 
Thread-1 try read Lock A 
Thread-1 read Lock A 
Thread-1 release read A 
Thread-1 release read B 
3 

? Thread-0은 thread-1에 의해 잠금이 해제되기 전에 어떻게 read()에서 critical 섹션에 들어가고 A에 대한 잠금을 얻는가? 출력이 동기가 아니기 때문에 가능합니까? 교착 상태가이 코드에서 발생하지 않습니다.

답변

5

DeadLockRisk의 다른 인스턴스를 두 스레드에 모두 전달하므로 동일한 개체에서 동기화되지 않습니다.

+0

ups, 빠르다, 나는 바보이다 ;-), 감사합니다 –

+0

@ justus.gadient.xyon,이 대답을 원한다면 왼쪽의 체크 아이콘을 클릭하여 '대답' – akf

1

두 DeadlockRisk 인스턴스 모두 resourceA 및 resourceB 필드에 대해 다른 인스턴스를 갖습니다. 예상대로 코드를 수행하려면 인스턴스 필드를 정적 필드로 변경하십시오.

+0

1 밀리 초, 우리는 혼란 ;-) ... 자바/예제 $ 자바 DeadLockRisk 스레드 0 잠금 B 읽어보십시오 스레드 1 잠금 쓰기 시도해보십시오 스레드 0 읽기 잠금 B 스레드 1이 쓰기 잠금 A 스레드 -0 시도 읽기 잠금 A 스레드 -1 시도 쓰기 잠금 B –