2015-01-24 3 views
-1

모두. Java 대기 알림 메커니즘에 대한 질문이 있습니다. 대답은 스레드가이 순서대로 실행된다는 보증입니다. 결과는 항상 100, 99, ..., 1이 될 것입니다. 이 코드의 조각입니다 :자바 - 대기 후 실행 순서

공용 클래스 홈페이지 {

static int counter = 0; 
static Object o = new Object(); 

public static void main(String[] args){ 

    for(int i = 0; i < 100; ++i){ 
     new Thread(() -> { 
      synchronized (o) { 
       try { 
        int c = ++counter; 
        o.wait(); 
        System.out.println("" + c); 
        Thread.sleep(100); 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 

    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    synchronized (o) { 
     new Thread(()-> { 
      synchronized(o){ 
       System.out.println("LAsttttttttttttttttt"); 
      } 
     }).start(); 


     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     o.notifyAll(); 
    } 

} 

}

내가 10 번을 실행하고 결과는 항상 동일합니다. 나는 인터넷에서 이것에 관해 무엇인가 발견하지 못했다. 또 하나의 질문 - 우리가 100 개의 스레드를 기다리고있을 때, 우리가 알릴 때 대기중인 스레드 중 첫 번째 스레드가 실행되고, 그 다음에는 두 번째 스레드와 100 개의 대기중인 스레드가 모두 실행 된 후에 다른 대기 메서드가 실행된다는 보장이 있습니다. synchronized 블록에서는 wait()가 없으므로) (대기중인 100 개의 모든 스레드가 실행 된 후) 실행됩니다. 또는 notifyAll은 대기중인 모든 스레드가이 객체와 동기화 된 모든 메소드와의 전투를 시작한다는 것을 보장합니다. 나는 이것이 대답이라고 생각합니다 : "깨운 스레드는 현재 * 스레드가이 객체에 대한 잠금을 해제 할 때까지 계속 진행할 수 없습니다. 깨어 난 스레드 *은 다른 스레드와 일반적인 방식으로 경쟁합니다. * 적극적으로이 개체를 동기화하기 위해 경쟁해야합니다 (예 : ) 깨운 스레드는 *에서이 개체를 잠그는 데 쓰레드로 사용할 수있는 신뢰할 수있는 권한이나 단점을 얻지 못합니다. "

하지만 기다림 통보가있을 때 무슨 일이 벌어지고 있는지 이해하고 싶습니다. 미리 감사드립니다.

답변

2

No. awoken 쓰레드가 특정 순서로 실행된다는 보장은 없습니다. (이것은 JVM의 특정 구현이나 프로그램이 실행되는 컴퓨터의 속도 또는 다른 많은로드 기반 변수로 인해 순서대로 발생할 수 있지만 언어 보증은 없습니다.)

+1

+1. 이러한 보장이 필요한 경우 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html#ReentrantLock%28boolean%29를 사용하십시오. –

2

Java의 동기화 된 코드 블록은 동기화 된 블럭에 들어가기를 기다리고있는 쓰레드가 들어갈 수있는 순서가 보장되지 않으며, notifyAll()은 특별한 경우로 나타나지 않습니다.

재개 된 스레드가 현재의 thread가이 오브젝트의 락을 해제 할 때까지는 진행될 수가 없습니다 : 당신이 notifyAll()의 javadoc (강조 광산)에서 보았 듯이

. 각성 된 스레드는 일반적인 방식으로과이 개체에서 동기화를 위해 적극적으로 경쟁 할 수있는 다른 스레드와 경쟁합니다. 예를 들어 깨운 스레드는이 개체를 잠그는 다음 스레드가 될 때 신뢰할 수있는 권한이나 단점을 갖지 않습니다.