가시성이라는게 쓰기는 아니고 읽기에 관련된 내용인거고, 읽기 동기화라고 불러도 될듯.
메모리상의 공유된 변수를 여러 스레드에서 사용할 수 있게 하려면 반드시 동기화 기능을 구현해야 한다고 함
(만약 읽기만 하면 동기화 안해도 되겠지?)
코드 재배치
메모리 상의 변수를 대상으로 작성해둔 코드가 '반드시 이런 순서로 동작할 것이다'라고 단정지을 수 없다고 함...
그래서 여러 스레드가 사용하는 변수는 항상 적절한 동기화 기법을 적용해야 한다고 함..
약한? 동기화 기능을 제공해주는거라고 함.
volatile로 선언된 변수의 값을 바꿨을 때, 다른 스레드에서 항상 최신의 값을 읽어갈 수 있도록 보장해준다고 함.
프로세서, 프로세서 외부에 캐시되지 않는다고 함.
volatile boolean asleep;
...
while(!asleep){
countSheeps();
}
정리하면 연산의 단일성은 보장하지 못하고, 가시성만 보장한다.
공개(published)
public static final String SAMPLE = "sample string";
public String getString(){ return SAMPLE;}
유출(escaped)
의도적으로 공개하지 않았는데 외부에서 사용할 수 있게 공개된 경우를 유출 상태라고 함...
생성자 안전성...
thread confine.
특정 객체가 단일 스레드에서만 사용된다고 확신할 수 있으면 동기화가 필요 없음
스택 한정 기법
primitive 타입의 로컬 변수를 이용하여 스레드 한정
객체형 로컬 변수는 외부로 공개될 때 문제가 생길 수 있음
ThreadLocal
스레드 한정을 도와주는 방법 중 하나..
실제 구현이 아닌 개념적으로는 ThreadLocal는 Map<Thread,T>같은 구조라고 함.
static으로 선언된 ThreadLocal에 스레드 단위로 트랜잭션 컨텍스트를 넣어두면 편리하다고 하는데..
안 해봐서 공감 안 됨....
불변 객체도 동기화 안해도 멀티 스레드에서 안전하게 사용 가능.
객체의 상태가 변하는게 문제인데, 불변 객체는 안 변하니까.
객체가 불변이라는 것과 참조가 불변이라는 것은 구분해야 함
...
소스코드의 특정 블록을 동기화시키려고 하면 메모리 가시성(memory visibility) 문제가 발생?
메모리 가시성 문제가 정확히 뭐지?
소스코드랑 뭔 상관?
코드 재배치의 경우...
컴파일러나 프로세서, JVM 등이 코드가 실행하는 순서를 바꾼다는데... 실제 예제 좀 보고 싶다..
진짜 내가 작성했던 코드 중에도 그런게 있었을까..?
volatile 적용해야 할 때를 알아채기 힘들듯.
생성자 안전성 잘 이해안됨
ThreadLocal, 관련된 멀티스레드 관련 코드 작성해보기
ThreadLocal이 재사용성을 떨어뜨리는 이유는?
c++에서 const와 java에서 final의 차이
초기화 안전성?
객체의 생성메서드가 제대로 완료되지 않은 상태라는게...
예를 들어 예외가 발생해서 제대로 완료되지 않은 경우를 말하는건가?
-> 그런듯..