🔥 Vamos/Basic

0410 | 스레드와 비동기처리_강의요약(1) // 프로세스, 동기 & 비동기식 실행, 문맥스위칭 (context switching)

unikue 2023. 4. 10. 23:19

[1] 스레드관해서 알아야 할 개념들
스레드 개념 : 비동기 처리를 위한 것
스레드 관리
동기화
동기화도구
스레드 풀
스레드에 안전한 콜렉션
포크/조인

[2] 멀티태스킹과 프로세스, context switching
✔ 프로세스

: 메모리에 올라가서 실제로 동작중인 프로그램

 

멀티태스킹/멀티프로세스 

:  os가 시분할(time share)을 통한 동시 실행을 지원

 

context switching

: 각 프로세스가 조금씩 돌아가다 멈추면서 순환되므로, 프로세스마다 문맥 개체를 가지고 있어야 한다.

: 자신이 어디까지 진행되었는지 기억해두었다가 차례가 오면 할당된 시간 동안 실행됨!

[3] 자식프로세스를 많이 가지는 일부 프로세스 > 백그라운드(비동기형) 작업의 필요성
동기식 실행

: 순서를 기반으로 하는 순차적인 흐름 (차례로 줄서서 실행되고 끝나는것) 
: 프로세스 내 자식 프로세스들로 비동기를 구현할 경우 프로세스간 할당되는 시간 격차로 컨텍스트 스위칭에 대한 부담 발생

: 자식이 많은 프로세스만 일방적으로 실행되게 된다

 

1. 형평성 문제 해결 필요
2. 스위칭 시간 줄이기
3. 자식-조상 프로세스간 데이터 공유 필요
👉 시분할에 프로세스간 스위칭 뿐만 아니라 부가적인 내용이 필요하게됨

[4] 프로세스의 문맥스위칭에서 스레드의 문맥스위칭으로 변화
: 프로세스 단위로 시간 분할이 아닌, 더 작은 단위를 필요로 하게 됨
: 시간 분할의 계층화 = 스레드 개념으로 시간분할하게 됨
: 프로세스에게 시간 할당 - 프로세스 내에서 (별도 프로세스가 아닌) 하부 단위에게 나눠서 시간을 분할함. 나눌수 있는 단위 = 스레드

✔ 장점

: 프로세스간 형평성 해소/ 내부적으로 비동기식 흐름. 
: 스레드들끼리 공유가 쉬움. (힙, 데이터 영역은 공유하고 스택만 스위치됨)

 

[5] 동기식 실행 예제

public class Ex1Program {

	public static void main(String[] args) {
		print1();
		print2();
		
		for(int i=0; i<20; i++)
			System.out.printf("main:%d%n",i+1); 
            // sub1>sub2>main 가 순차적으로 동기식 처리. 메인스레드 1개만 존재
	}

	private static void print2() {
		for (int i = 0; i < 20; i++)
			System.out.printf("sub2:%d%n", i+1);
	}

	private static void print1() {
		for (int i = 0; i < 20; i++)
			System.out.printf("sub1:%d%n", i+1);
	}
}

 

[6] 비동기식 실행 예제- 메인스레드 외에 보조스레드 호출

: 보조 스레드를 위해 약속된 시작함수 : run() 👉 Runnable 인터페이스를 구현한 메소드
: 스레드가 준비가 되면 start()메서드로 호출해 줘야 작동이 가능하게된다 (*run을 바로 실행할 수는 없고 스레드를 큐에 담아서 실행하기 때문)

	public static void main(String[] args) {
		Thread th1 = new Thread(new Runnable() {
        // Runnable은 추상메소드 run()하나만 구현되어있어 익명메소드 구현 가능

			@Override
			public void run() {
				print1();
			}
		});

		Thread th2 = new Thread(new Runnable() {

			@Override
			public void run() {
				print2();
			}
		});

		th1.start();
		th2.start();

		for (int i = 0; i < 15; i++)
			System.out.printf("main:%d%n", i + 1);
	}

	private static void print2() {
		for (int i = 0; i < 15; i++)
			System.out.printf("sub2:%d%n", i + 1);
	}

	private static void print1() {
		for (int i = 0; i < 15; i++)
			System.out.printf("sub1:%d%n", i + 1);
	}

 

 

메인/sub1/sub2가 각자의 속도로 실행된다