본문 바로가기

Synchronized (동기화) in Java

자바는 멀티스레드 환경을 지원한다.

 

멀티스레드는 여러개의 일을 동시에 처리할 수 있어 시간 효율성이 좋지만, 같은 자원에 접근하고 수정할 수 있어 다양한 공유자원 문제들이 생긴다. 기술적인 관점에서 자바를 실행하는 자바 가상 머신, 즉 JVM은 여러개의 스레드로 이루어져 있다.

 

그러나, 기본적으로 개발자의 관점에서는 싱글 스레드이다. 물론, 코드 작성을 통해 추가 스레드를 생성해서 실행시킬 수 있다.

 

공유자원 문제를 해결하기 위해서는, 하나의 쓰레드가 자원을 사용하고 있는 동안, 다른 쓰레드는 그 자원을 변경할 수 없어야 한다. 그래서 synchronized 동기화를 사용해야 한다. 2가지 방법이 존재한다.

 

1. synchronized method

메소드에 synchronized 키워드를 붙여 사용한다.

public synchronized void testFunction(int param) {
	// ...
}

하나의 스레드만이 위 메소드를 실행시킬 수 있다. 그러나, 동기화는 메소드 단위가 아닌 메소드를 지닌 객체 단위로 진행된다. 즉, Lock이 걸리는 건 Instance 이다. 단 synchronized 메소드에 한해서이다.

 

즉, 하나의 객체안에 여러개의 synchronized 메소드가 존재한다면, synchronized 메소드들은 동시에 실행 될 수 없다. 그러나, 다른 메소드는 가능하다.

 

1-1. static synchronized method

static 키워드를 붙이면, 클래스 단위로 동기화 시킬 수 있다. static 키워드를 붙이지 않았으면 객체 단위로 동기화, 붙이면 클래스 단위이다. 즉, static 멤버 변수를 동기화 시키기 위해서는 static 메소드가 필요하다.

 

2. synchronized block

메소드의 특정 부분만 동기화 하기 위해서는 block을 만들어야 한다. 이 떄 lock 할 객체를 지정해야 한다.

public void testFunction(int param) {
	// ...
	synchronized(this) {
		this.apple += param;
	}
	// ...
}

위 함수에서 쓰인 this는 해당 메소드가 존재하는 객체를 의미한다. block으로 감싸진 부분은 하나의 쓰레드만이 실행시킬 수 있다.

 

2-1 static synchronized block

static 이므로 this를 사용하지 않는다. 클래스 단위로 lock을 공유한다.

public static void testFunction(int param) {
	// ...
	synchronized(클래스이름.class) {
		this.apple += param;
	}
	// ...
}

'JAVA > JAVA' 카테고리의 다른 글

Garbage Collection - 가비지 컬렉션  (0) 2022.06.23
Java Virtual Machine (JVM) & 자바 컴파일  (0) 2022.06.23
객체지향 & 절차지향 언어  (0) 2022.06.22
JAVA - 특징  (0) 2022.06.20