while(1) work();
반응형

문제

class Q5 {
    static Integer value = 0;

    public static void main(String[] args) throws InterruptedException{
        Runnable r = () -> {
            for (int i = 0; i < 100000; i++) {
                synchronized (value) {
                    value++;    
                }
            }
        };

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("value = " + value);
    }
}

이 출력값은 200000인가?

 

Hint: 문제 2번과 유사하다. ( https://blog.youhogeon.com/180 )

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

정답

아니다.

문제 2번과 같이 200000에 못미치는 값이 출력된다.

 

synchronized의 락 객체로 value를 지정하였으나, 이 value객체는 값이 바뀜에 따라

unwrapping되고 다시 새로운 객체로 wrapping된다.

 

즉 락에 사용된 객체는 버려지고(GC의 대상) 새로운 값을 가지는 Integer 객체가 생성된다.

Integer는 불변 객체이기 때문이다.

 

따라서 기존 객체의 락이 사용되고 있음에도 불구하고

새로 진입하려는 쓰레드는 기존 객체가 아닌 새로 생긴 객체의 락을 획득할 수 있다.

 

그래서 synchronized 블록에 진입할 수 있다.

 

synchronized (new Object()) {
    value++;    
}

이렇게 작성하면 안되는 이유이기도 하다.

 

 

추천 글 : https://stackoverflow.com/questions/9749746/what-is-the-difference-between-atomic-volatile-synchronized

반응형
profile

while(1) work();

@유호건

❤️댓글은 언제나 힘이 됩니다❤️ 궁금한 점이나 잘못된 내용이 있다면 댓글로 남겨주세요.

검색 태그