2017-03-26 8 views
0
public class Test { 
    public static String str = "abc"; 

    public static void main(String[] args) { 
     System.out.println("before run" + str); 
     for (int i = 0; i < 5; i++) { 
      new Thread(new Runnable() { 
       public void run() { 
        try { 
         Thread.sleep(100); 
        } catch (InterruptedException e) {;} 

        str =str +"1"; 
       } 
      }).start(); 
     } 
     System.out.println("after run" + str); 
    } 
} 

나는 불변의 String 클래스에 대한 테스트, 그것은 내가 동기화 된 물건을String은 JAVA에서 불변의 클래스인가? 그렇다면이 기능을 사용하는 방법은 멀티 스레드 프로그래밍입니까?

할 필요 없다 생각 때문에 스레드 안전 클래스입니다 그러나 결과는 와 함께 보여줍니다 때 "ABC 전에"저를 충격했다 와 "abc 후에".

내가 그 Thread.sleep (100)을 제거했을 때; 결과는 "abc before"및 "abc1111 after"가되었습니다.

public static String str이 수정 되었습니까? 그 이유는 무엇입니까?

+2

당신은 *, 당신이하고있는 * 문자열을 수정하지 않을 수 없습니다와는 아무 상관 없습니다 변수를 참조하는 * 수정. 왜 너 한테 줄까? – shmosel

+0

"(실행 전"과 같이) 문자열의 값을 수정할 수 없다는 것을 알지 못합니다 ... 실제로 변수의 값을 변경할 수는 있지만 유형이 변경되지 않는 것과는 아무런 관련이 없습니다 ... –

+1

'문자열을 변경하지 마십시오 (문자열은 변경되지 않으므로 불가능합니다). 정적 변수에 새 문자열을 지정합니다. 그것은 불변성과 스레드와 아무 관련이 없습니다.'String s = "a"를 할 수있는 가능성에 대해서만; s = "b";'. –

답변

0

불변이란 개체의 내용을 변경할 수 없음을 의미합니다. 변경할 수있는 객체 (예 : array, ArrayList, Date)를 사용하면 해당 객체의 내용을 변경할 수 있습니다. 하지만 문자열로는 그렇게 할 수 없습니다. 이 예제는 한 객체에 대한 참조를 다른 객체에 대한 참조로 바꾸는 것을 보여줍니다.

이 대체를 허용하지 않으려면 변수를 final로 지정하십시오.

+0

많은 분들께 감사드립니다. 나는 '불변성'의 의미를 오해하고 있습니다. – stewieissucker

0

public static String str이 수정 되었습니까?

그것은 참조 변수 오히려 str 포인트 (JVM에 의해 유지되는 문자열 상수 풀에서) 다른 객체 당신이 연결 (+) 연산 즉 수행하는 각 시간, 같은 String 객체을 수정하지 않았다 , 기존 문자열 객체는 삭제됩니다.

Immutability를 사용하면 생성 된 기존 객체 내용을 변경할 수 없으며 스레드 안전성과 관련하여 유용합니다. 즉, 다중 스레드 쓰기/읽기에서 객체를 보호하기 위해 명시 적 동기화/잠금이 필요하지 않습니다. .

0

다른 말로는 String과 같은 불변 개체를 수정할 수 있지만 참조 변수가 어떻게 수행 중인지와 같은 다른 문자열을 가리 키도록 변경할 수 있습니다.

수면 메서드가 제거되거나 주석 처리 된 스레드 중 일부 스레드가 빠르게 실행되어 str 변수 참조가 연결된 문자열을 가리 키도록 업데이트되므로 출력이 달라집니다. 이것이 수면 방법을 제거하여이 프로그램을 실행하면 아래 표시된 것처럼 다른 출력이 표시 될 수 있습니다. 절전 방법은 제거되지 않습니다

after abc1 
after abc11 
after abc1 
after abc 

하지만, 메인 스레드가 대기하는 다른 모든 스레드가 완료되기도 전에 완료, 그것은 당신이 연결이에 의해 발생하지 않을 수 있습니다로 출력으로 "ABC 후"주로 참조하는 방법입니다 time 메인 쓰레드는 마지막 print 문에 도달한다. 그러나 수면 시간을 5 밀리 초로 줄이고 "abc1 이후"로 출력을 볼 수 있습니다.

그래서, 기본적으로 출력은 메인 쓰레드가 마지막 인쇄 문에 도달하는 속도에 따라 달라집니다 그리고 문자열이 불변 인 또는