Deperecated/JAVA

JAVA - 멀티 쓰레드

누알라리 2020. 1. 17. 16:58

1. 프로세스

운영체제에서 실행중인 하나의 애플리케이션.

사용자가 앱을 실행하면 운영체제로 부터 실행에 필요한 메모리를 할당 받아 앱의 코드를 실행하는데, 이를 프로세스라 한다.

 

2. 쓰레드

한 가지 작업을 실행하기 위해 순차적으로 실행할 코드를 실처럼 이어놓았다는 뜻.

 

3. 멀티쓰레드

한 프로세스 내에 스레드가 두 개 이상인 것.

하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를 발생시키면 프로세스 자체가 종료될 수 있다.

예외처리에 신경써야 한다.

 

4. 멀티쓰레드의 사용처

  1. 대용량 데이터의 처리 시간을 줄이기 위해 데이터를 분할해 병렬로 처리하는 곳
  2. UI를 갖고있는 애플리케이션에서 네트워크 통신을 하기위해 
  3. 다수의 클라이언트의 요청을 기다리는 서버 개발

5. 작업 쓰레드 생성과 실행

메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성하면 된다.

JAVA에선 작업 스레드도 "객체"로 생성되기 때문에 클래스가 필요하다.

 

  1. java.lang.Thread 클래스를 직접 객체화하여 생성
  2. Thread를 상속해서 하위 클래스를 생성하여 생성

5-1. Thread 클래스로부터 직접 생성

Thread 클래스로부터 작업 스레드 객체를 직접 생성하려면 Runnable 인터페이스를 매개값으로 갖는 생성자를 호출해야 한다.

Runnable은 인터페이스 타입이기 때문에 구현 객체를 만들어서 대입해야 한다.

// Runnable 객체는 작업 내용을 갖고있는 객체이지 실제 스레드는 아니다.


public class H_Run implements Runnable {
	public void run() {
		
		// 스레드가 실행할 코드
		for(int i=0; i<5; i++)
		{
			System.out.println("띵");
			try { Thread.sleep(500); } catch(Exception e) {}
		}
	}
}
public class H_Main {

	
	public static void main(String[] args) {

		// 1. 구현 객체를 만들어서 Thread 생성자를 호출하며 작업 스레드를 생성하는 경우
		Runnable task = new H_Run();

		Thread thread = new Thread(task);


		// 2. 익명 구현객체를 사용하는 경우
		Thread thread2 = new Thread(new Runnable() {
			public void run()
			{
				System.out.println("오버라이딩");
			}
		});
        
        3. 람다식으로 생성하는 경우
		
		// 스레드 실행
		thread.start();
		thread2.start();
	}
}

 

5-2. Thread 하위 클래스로부터 생성

Thread를 상속받는 자손 클래스에 스레드가 실행할 코드를 작성한 후, 이를 main에서 Thread 객체로 만들어 스레드를 수행시킬 수 있다.

public class H_Run extends Thread{
	
	public void run()
	{
		System.out.println("스타벅스");
	}
}
public class H_Main {
	
	public static void main(String[] args) {
		
		Thread task = new H_Run();
		
		task.run();
	}
}

 

6. 스레드의 이름

스레드의 이름을 갖고올 수 있는 함수들이 존재한다.

이 함수들은 스레드 객체의 참조가 필요하다.

 

메소드 설명
void setName("스레드이름") 스레드 이름으로 설정
string getName(); 스레드 이름 가져옴
Thread currentThread(); 현재 스레드의 참조를 얻음.

 

public class H_Main {
	
	public static void main(String[] args) {
		
		// 코드를 실행하는 현재 스레드의 참조를 얻을 수 있다.
		Thread mainThread = Thread.currentThread();
		
		System.out.println(mainThread.getName());
		
		H_Run secondThread = new H_Run();
		
		System.out.println(secondThread.getName());

		secondThread.setName("아이우에오쓰레드");
		
		System.out.println(secondThread.getName());
	}
}

 

7. 스레드 우선순위

멀티스레드는

  1. 동시성
  2. 병렬성

으로 진행된다.

 

7-1. 동시성

하나의 코어에서 멀티 스레드가 번갈아가며 실행되는 성질

 

7-2. 병렬성

멀티 코어에서 개별 스레드를 동시에 실행하는 성질

 

8. 스레드 스케줄링

스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해 동시성으로 실행할 것인가 결정해야하며, 이를 스레드 스케줄링이라 한다.

스레드 스케줄링에 의해 스레드들은 아주 짧은 시간에 번갈아가면서 그들의 run() 메소드를 실행시킨다.

 

스레드 스케줄링은

  1. 우선순위 방식
  2. 순환할당 방식

을 사용한다.

 

8-1. 우선순위 방식

우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링 하는 것.

개발자가 코드로 객체에 우선 순위를 부여한다.

 

1~10까지 부여되고, 1이 가장 우선순위가 낮으며 디폴트로 5가 배정된다.

thread.setPriority(우선순위);

최소한 5개 이상의 스레드가 실행되어야 우선순위의 영향을 받는다.

 

8-2. 순환 할당 방식

시간 할당량(Time Scale)을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식.

JVM에 의해 정해지기 때문에 코드로 제어할 수  없다.

 

 

9. 동기화 메소드&동기화 블록

 

9-1. 공유 객체를 사용할 떄의 주의점

멀티스레드 프로그램에서는 객체를 공유하는 경우가 생기는데, 잠금을 안걸어놓으면 A가 쓰다가 B가 바꿔놓으면 A는 엉터리값을 쓰게되는 경우가 있다.

 

따라서 스레드 작업이 끝날 때 까지 객체에 잠금을 걸어서 다른 스레드가 사용할 수 없도록 해야한다.

 

9-2. 임계 영역(critical section)

멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역

JAVA는 임계 영역을 지정하기 위해 동기화(synchronized) 메소드와 동기화 블록을 제공한다.

 

9-3. 동기화 메소드 및 동기화 블록

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

JAVA - 주요 API 정리  (0) 2020.01.16
JAVA - 중첩 클래스&중첩 인터페이스  (1) 2020.01.11
JAVA - 예외 처리  (0) 2020.01.10
JAVA - 익명 구현 객체, 람다식  (0) 2020.01.09
JAVA - 인터페이스  (0) 2020.01.09