2012-05-18 3 views
0

에 동결이 내 간단한 프로그램입니다 : 당신이 볼 수 있듯이자바에서 7 64 비트 내 프로그램은 루프

public class Test { 
    public static Object obj = null; 

    public static void main(String[] args) { 
     obj = null; 
     System.out.println("Start"); 
     MyThread myThread = new MyThread(); 
     myThread.start(); 
     while(obj == null) { 
      //System.out.println(""); 
     } 
     System.out.println("Stop"); 

    } 
} 

class MyThread extends Thread { 

    @Override 
    public void run() { 
     System.out.println("Thread 1"); 
     try { 
      sleep(1); 
     } catch (InterruptedException ex) { 
     } 
     System.out.println("Thread 2"); 
     Test.obj = new Object(); 
     System.out.println("Thread 3"); 
    } 
} 

, 나는 MyThread 스레드를 실행하고 테스트 클래스의 루프 동안. 루프는 obj가 null인지 검사하고 그렇지 않으면 중지하고 "2"를 인쇄합니다. MyThread는 obj에 값을 할당합니다. 이제 문제가 생겼습니다 :

Java 7 64 비트에서 빈 while 루프의 경우 절대로 중지되지 않습니다. 그러나 System.out.print ("") 주석 처리를 제거하면 루프 아래의 "Stop"이 인쇄됩니다. 그러나 루프 내부의 다른 명령문 (예 : int i = 1;)의 경우 프로그램이 멈 춥니 다. Java 32 비트에서는 모든 경우에 모든 것이 잘 작동합니다.

누군가이 이상한 행동을 설명 할 수 있습니까?

감사합니다.

+0

호기심에서 벗어난 프로그램이 멈 추면 "Thread1", "Thread2" "Thread3"라는 인쇄물이 나옵니까? – jogabonito

답변

3

코드가 스레드로부터 안전하지 않습니다. 스레드의 Test.obj에 대한 할당은 어떤 형태의 동기화없이 주 스레드에서 표시되는 것이 보장되지 않습니다.

동기화 된 정적 getter/tester/setter 메소드를 제공하면 (모든 액세스가 이러한 메소드를 통과하는 한) 올바르게 구현할 수 있습니다. 다른 대안이 존재합니다.

+1

+1; btw : 변수'volatile'을 표시하면 즉시 작동합니다 ... – home

+0

'volatile' 너무 까다 롭습니다. 질문자가 동기화 문제를 매우 명확하게 이해하지 않는 한 제안하지 마십시오. 물론 – Mat

+0

, 나는 동의한다. – home

2

자바에도 volatile 키워드가 있다는 것을 기억하십시오. 이 특별한 예제의 경우 - Java 캐시 obj 캐시합니다.

관련 문제