숑숑이의 개발일기
article thumbnail

프로그램과 프로세스

쓰레드의 개념을 명확히 알기 위해서는 우선 컴퓨터의 구조를 이해할 필요가 있다. 컴퓨터를 이루는 주요 구성 요소에는 중앙 처리 장치(CPU), 메모리(memory), 하드디스크(hard disk)가 있다. CPU는 연산을 수행해 실제 프로그램을 실행하는 장치이고, 가장 빠른 속도로 동작한다. 

 

프로그램은 하드디스크에 저장된 파일들의 모임, 프로세스는 메모리상에 로딩된 프로그램을 의미한다. 메모리는 그때그때 필요한 부분만을 동적으로 로딩한다.

 

쓰레드(Thread)란?

오직 프로세스만 CPU를 사용할 수 있다. 프로세스를 구성하는 작업의 한 단위로 다르게 말해 쓰레드는 CPU를 사용하는 최소 단위라고도 말할 수 있다.

 

  • 싱글스레드 프로세스: 프로세스 내에서 단 하나의 스레드만 작업
  • 멀티스레드 프로세스: 여러 스레드가 같은 프로세스 내의 자원을 공유해서 작업

 

멀티 쓰레드에서는 동시성 또는 병렬성을 갖고 처리된다.

동시성

처리할 작업의 수가 CPU의 코어 수보다 많을 때. 이때 CPU는 각 작업 쓰레드의 요청 작업을 번갈아가면서 수행한다. 매우 짧은 간격으로 교차 실행하므로 사용자는 두 작업이 마치 동시에 실행되는 것처럼 보인다.

 

병렬성

CPU의 코어 수가 작업 수보다 많을 때에는 각각의 작업을 각각의 코어에 할당해 동시에 실행할 수 있다.(=동시에 작업이 수행된다)

 

만약 작업의 수가 6개, 코어가 2개라면?
스레드의 동시성과 병렬성이 함께 적용된다. 먼저 작업이 2개의 코어에 나뉘어 할당되고(병렬성), 각각의 코어는 할당된 작업을 번갈아 실행할 것이다.(동시성)

 

멀티 스레드의 목적은 병렬성과 동시성을 활용해 여러 작업을 동시에 실행하거나 동시에 실행하는 것처럼 보이게 하는 것이다.

 

자바 언어 명세상 long과 double 외의 변수를 읽고 쓰는 동작은 원자적(atomic)이다. 

JVM은 데이터를 4byte(=32bit)단위로 처리하기 때문에, int와 int보다 작은 타입들은 한 번에 읽고 쓰는 것이 가능하다. 즉 즉 하나의 명령어로 읽거나 쓰기가 가능하다는 것. 하나의 명렁어는 더 이상 나눌 수 없는 최소의 작업단위이기 때문에 작업 중간에 다른 스레드가 끼어들 틈이 없다. 

 

동기화(sychronized)란?

하나의 작업이 완전히 완료된 후 다른 작업을 수행하는 것을 말한다. 한 스레드가 진행 중인 작업을 다른 스레드가 간섭하지 못하도록 막는 것을 스레드의 동기화(synchronization)라고 한다. 멀티 스레드 환경에서 문제없는 프로그램을 제작하기 위해서는 동시성 문제, 데드락과 같은 여러 가지 문제점을 해결해야 한다. 

동기화는 스레드 사이의 안정적인 통신에 꼭 필요하다.

 

메서드 동기화

2개의 쓰레드가 동시에 메서드를 실행할 수 없다는 것을 의미한다. 메서드의 리턴 타입 앞에 synchronized 키워드를 작성한다.

class MyData {
	int data = 3;
    public synchronized void plusData() {
    	// data 필드의 값을 +1 수행
    }
}

 

블록 동기화

2개의 쓰레드가 동시에 해당 블록을 실행할 수 없다는 것을 의미한다. 멀티 스레드를 사용하는 프로그램이라 하더라도 동기화 영역에서는 하나의 스레드만 실행할 수 있기 때문에 성능 면에서 많은 손해를 보기 때문에 동기화 영역은 꼭 필요한 부분에 한정해 적용하는 것이 좋다. 

class MyData {
	int data = 3;
    public void plusData() {
    	synchronized (this) {	// 일반적으로는 this를 넣어 자기 객체를 가르킴
        	// data 필드의 값을 +1 수행
        }
    }
}

 

this의 경우 모든 클래스 내부에서 객체의 생성 과정 없이 바로 사용할 수 있기 때문에 일반적으로 this를 사용한다.

 

오늘의 질문

하나의 쓰기 스레드와 여러 읽기 스레드가 존재할 때 사용되어야 하는 Java의 동기화 기능은 무엇이고 어떻게 동작하게 될까?

 

우선 하나의 쓰기 스레드와 여러 읽기 스레드가 공유하는 리스트가 있다고 가정한다. 당연히 각 스레드에서 리스트의 상태가 일관성 있게 유지되어야 할 것이다. synchronized 키워드를 사용하여 쓰기 작업이 진행되는 동안 읽기 작업이 차단되도록 만들면 된다. 이를 통해 공유 자원에 대한 동시 접근을 제한하고, 데이터 무결성을 유지할 수 있다.

 

https://velog.io/@may_yun/Java-Multi-thread-동기화-기능
profile

숑숑이의 개발일기

@숑숑-

풀스택 개발자 준비중입니다