Java synchronized keyword
synchronized block은
synchronized
키워드로 표시합니다.Synchronized instance methods
synchronized
키워드는 메서드에도 적용할 수 있습니다.인스턴스 메서드를 synchronized로 선언하는 것은 한 시점에 하나의 쓰레드만 해당 메서드를 실행 할 수 있음을 의미합니다.
Synchronized blocks inside instance methods
전체 메서드를
synchronized
로 선언하고 싶지 않다면 synchronized block을 활용할 수 있습니다. synchronized block 역시 한 시점에 하나의 쓰레드에 의해서만 실행 될 수 있습니다. 동기화 블럭을 선언할때 괄호 안에 작성한 this는 monitor object 입니다.
모니터 객체는 동기화의 범위를 나타냅니다.
동기화 메서드는 자동적으로 this 범위의 동기화 범위를 가집니다.

위 코드에서 모든 메서드는 같은 monitor 객체 (this)를 가지기 때문에 Thread 1 이 setObject를 호출하는 순간 Thread 2는 getObject를 호출 할 수 없습니다. (동기화 블럭으로 선언된 xxxObj 메서드 들도 마찬가지)

Example of threads calling synchronized instance methods on a shared object
실행 결과
thread 2가 thread 1 이 set하기도 전에 접근해서 getObj할때 null을 반환한다.
Synchronized static methods
static 메서드의 경우 클래스 객체를 모니터 객체로 활용한다.

전체 쓰레드에서 한 쓰레드만이 synchronized static 메서드를 호출 할 수 있다.
Using both synchronized static and instance methods
한 클래스에 선언된 synchronized 메서드 일지라도 서로 다른 monitor 객체를 가질 수 있다. static method의 경우 클래스 객체에 instance method의 경우 자신의 참조 (this)를 monitor 객체로 가진다.
Using different monitor objects for synchronized blocks within same class
이경우 intCounterN 메서드는 두개의 카운터 필드는 서로 다른 모니터 객체에 의해 동기화 되므로 서로다른 쓰레드에 의해 동시에 실행 될 수 있습니다.
Sharing monitor objects across different class instances (objects)
Monitor objects cannot be null
- 모니터 객체는 null이 될 수 없다.
- 모니터 객체가 null일 경우 동기화 메서드/ 블락 진입시 null pointer exception이 발생한다.
Example of sharing monitor objects across objects
매우 멋지고 Advanced 한 기술이고 잘 쓰면 Fancy한 동기화 기술을 사용할 수 있지만 정말 잘 동기화 하고 있는가에 대한 검증은 매우매우 어려워진다.
Don't use String constant objects as monitor objects
자바 컴파일러가 마구마구 최적화 해버린다. 같은 instance 임을 보장 할 수 없음.
마찬가지로 Wrapper 클래스도 사용하면 안된다.
Java synchronized blocks inside Java Lambda Expressions
java 람다 표현식에서는 this라는 참조를 사용할 수 없으므로 monitor 객체로 this를 전달 할 수 없다.
Java synchronized block reentrance rules
incAndGet 메서드와 inc 메서드 모두 같은 모니터 객체인 this를 가지기 때문에 incAndGet 메서드에서도 inc를 진입할 수 있다.
Java synchronized block data change visibility guarantee

- all fields that are visible to Thread 1
- main memory → cache → registers of cpu 1
- 동기화 블럭을 제거하면 Thread 들 간에 count 필드를 언제 가져갔고 main memory에 최신상태로 다시 write 해 놓았는지에 대한 보장이 안됨
Java synchronized block visibility example
Java synchronized block happens before guarantee

Java syncronized block limitations
Limitations of Java synchronized blocks:
- Only one thread can enter a synchronized block at a time.
- There is no guarantee about the sequence in which waiting threads gets access to the synchronized block.
- no fairness → maybe starvation!
Java synchronized block performance overhead

Java syncrhronized blocks in clustered setups
Java는 같은 JVM 상의 쓰레드 끼리의 동기화만 제공한다.