"안녕, 아미고!"

"Java 메모리 모델이라는 거대한 주제가 있습니다. 기본적으로 아직 알 필요는 없지만 들어 보면 도움이 될 것입니다."

"잠재적인 모든 문제를 제거하기 위해 Java는 메모리 관리 메커니즘을 변경했습니다. 이제 메모리는 단순히 스레드의 로컬 캐시와 전역 메모리로 나뉘는 것이 아니라 메커니즘이 훨씬 더 좋아졌습니다."

"그리고 더 복잡해!"

"예, 더 좋고 더 복잡합니다. 비행기와 같습니다. 비행기로 비행하는 것이 걷는 것보다 낫지 만 더 복잡합니다. 새로운 상황을 아주 간단하게 설명하겠습니다."

"그들이 생각해낸 것은 다음과 같습니다. '이전 발생'이라는 로컬 스레드 메모리 동기화 메커니즘이 코드에 추가되었습니다. 몇 가지 규칙/조건이 발명되었습니다. 이러한 조건이 충족되면 메모리가 동기화되거나 현재 상태로 업데이트됩니다. 상태.

"다음은 예입니다."

주문하다 스레드 1 스레드 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
스레드가 뮤텍스가 해제되기를 기다리고 있습니다.

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

"이러한 조건 중 하나는 해제된 뮤텍스의 획득입니다. 뮤텍스가 해제되고 다시 획득되면 메모리는 획득 전에 동기화됩니다. 스레드 2는 변수 x 및 y의 '최신' 값을 볼 수 있습니다. 당신은 그것들을 휘발성이라고 선언하지 않습니다."

"얼마나 흥미롭군! 그리고 이런 조건이 많이 있지?"

"충분합니다. 다음은 메모리 동기화를 위한 몇 가지 조건입니다."

  • "단일 스레드 내에서 모든 명령은 소스 코드에서 뒤에 오는 모든 작업 전에 발생합니다 ."
  • " 동일한 잠금이 획득되기 전에 잠금 해제가 발생합니다."
  • " 동기화된 블록/방법이  동일한 모니터에 입력되기 전에 동기화된 블록/방법 에서 종료가 발생합니다."
  • " 동일한 휘발성 필드를 메모리에서 읽기 전에 휘발성 필드를 메모리에 쓰는 작업이 발생합니다 ."
  • "Thread 객체의 run 메서드의 끝은 join() 메서드가 종료되거나 isAlive() 메서드가 동일한 스레드의 객체에서 false를 반환하기 전에 발생합니다 ."
  • "Thread 객체의 start() 메서드에 대한 호출은 동일한 스레드의 객체에서 run() 메서드가 시작되기 전에 발생합니다 ."
  • "생성자의 끝은 이 클래스의 finalize() 메서드가 시작되기 전에 발생합니다 ."
  • "인터럽트() 메서드에 대한 호출은 InterruptedException이 발생했거나 isInterrupted() 또는 interrupted() 메서드를 사용하여 스레드가 이 메서드가 호출되었음을 확인하기 전에 발생합니다. "

"그래서 생각보다 좀 복잡하군요?"

"예, 조금 더 복잡합니다..."

"고마워, 리시. 생각해볼게."

"이 주제에 대해 너무 걱정하지 마십시오. 모든 것을 스스로 이해할 때가 올 것입니다. 지금은 기본을 이해하는 것이 더 좋을 것입니다. Java 머신의 내부 작동 Java 9가 출시되면 모든 것이 다시 변경됩니다."

"O_o. 그래... 어떤 것은 모르는 것이 낫다."