[Java] 프로세스(Process)와 스레드(Thread)

류넹·2023년 11월 27일
1

Java

목록 보기
18/20

# 목적

: 프로세스(Process)와 스레드(Thread)에 대한 이해



Process(프로세스)

- 하나의 프로그램이 실행될 때 운영체제로부터 실행에 필요한 자원을 독립적으로 할당받고 애플리케이션 실행에 필요한 환경을 제공한다.

- 실행중인 프로그램 하나당 프로세스가 하나씩 생긴다.

- 멀티태스킹(Multi tasking)
: 동시에 두개 이상의 프로세스(프로그램)의 실행을 지원하는 것.
프로세스마다 실행에 필요한 자원(CPU, 메모리)들을 적절히 할당하고, 관리하는 기술이 필요하다.




Thread(스레드)

- 프로세스가 수행문을 실행하기 위해서 사용하는 실행흐름(일꾼)
- 모든 프로세스는 하나 이상의 스레드를 가지고 있다.
ex) Java는 어플리케이션 실행 시 프로세스가 생성되고, 내부적으로 main 스레드가 수행문을 실행함

* 스레드 제어 관련 주요 메소드
sleep()          - 스레드 일시정지
yield()          - 다른 스레드에게 자원사용을 양보
join()           - 다른 스레드의 작업이 종료될 때까지 대기한 후 실행
wait(), notify() - 스레드 2개를 번갈아가며 실행
interrupt()      - 스레드를 강제로 종료




스레드 사용법

1번째 방법

1) 사용자 정의 스레드 생성하기 :

public class MyThread extends Thread {
    // run() 메소드 재정의
    public void run() {
        // 동시에 처리할 작업
    }
}

2) 사용자 정의 스레드 실행하기 :

MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();

t1.start();
t2.start();
t3.start();

run()은 별도의 스레드가 생성되는 것이 아님
start()는 새로운 스레드(일꾼)을 통해서 run()를 실행하게 함

start()가 아닌 run()으로 실행하면,
main스레드가 동시처리 안하고 순차적인 실행을 하게 됨



2번째 방법

- 부모클래스가 있을 땐 1번 방법의 extends Thread가 불가능하기 때문에 아래 방법 사용

1) 사용자 정의 스레드 생성하기 :

public class MyRunnable implements Runnable {
    // Runnable 인터페이스의 추상 메소드 run()을 구현
    public void run() {
        // 동시에 처리할 작업
    }
}

2) 사용자 정의 스레드 실행하기 :

MyRunnable myRunnable = new MyRunnable();
Thread t1 = new Thread(myRunnable);
Thread t2 = new Thread(myRunnable);
Thread t3 = new Thread(myRunnable);

t1.start();
t2.start();
t3.start();

* 참고)
메인스레드는 메인메소드 안에 있는 것만 실행
사용자 정의 스레드는 run() 안에 있는 것만 실행 가능





사용 예시

public class Server {
    Map<Integer, Handler> map = new HashMap<>();
    public Server() {
        // Map객체에 요청명령(1/2/3)별 Handler구현객체 저장
        map.put(REQ_FILE_LIST, new ServerFileListHandler());
        map.put(REQ_DOWNLOAD, new ServerFileDownloadHandler());
        map.put(REQ_UPLOAD, new ServerFileUploadHandler());
    }
    
    public void startup() {
        // 클라이언트의 연결요청을 처리하고, 클라이언트와 통신하는 소켓을 반환하는 객체
        ServerSocket serverSocket = new ServerSocket(30000);
        while (true) {
            // 서버소켓은 클라이언트의 연결요청이 접수되면 그 클라이언트와 통신하는 소켓을 반환
            Socket socket = serverSocket.accept();
            // 클라이언트와 통신을 담당하는 일꾼(스레드)객체 생성
            // map에는 클라이언트의 요청을 처리하는 데 필요한 Handler객체가 있다.
            // socket은 클라이언트와 연결된 스트림객체가 있다.
            ServerThread thread = new ServerThread(map, socket);
            thread.start();
        }
    }
}

public class ServerThread extends Thread {
    Map<Integer, Handler> map;
    Socket socket;
    
    DataInputStream in;
    DataOutputStream out;
    
    public ServerThread(Map<Integer, Handler> map, Socket socket) {
        this.map = map;
        this.socket = socket;
        
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
    }
    
    // 스레드가 수행할 작업 작성
    public void run() {
        while (true) {
            // 클라이언트가 요청한 요청명령 조회하기
            int reqCmd = in.readInt();    // 1, 2, 3 중 하나
            Handler h = map.get(reqCmd);
            h.handle(in, out);
        }
    }
}
profile
학습용 커스터마이징 간단 개발자 사전

0개의 댓글