: 프로세스(Process)와 스레드(Thread)에 대한 이해
- 하나의 프로그램이 실행될 때 운영체제로부터 실행에 필요한 자원을 독립적으로 할당받고 애플리케이션 실행에 필요한 환경을 제공한다.
- 실행중인 프로그램 하나당 프로세스가 하나씩 생긴다.
- 멀티태스킹(Multi tasking)
: 동시에 두개 이상의 프로세스(프로그램)의 실행을 지원하는 것.
프로세스마다 실행에 필요한 자원(CPU, 메모리)들을 적절히 할당하고, 관리하는 기술이 필요하다.
- 프로세스가 수행문을 실행하기 위해서 사용하는 실행흐름(일꾼)
- 모든 프로세스는 하나 이상의 스레드를 가지고 있다.
ex) Java는 어플리케이션 실행 시 프로세스가 생성되고, 내부적으로 main 스레드가 수행문을 실행함
* 스레드 제어 관련 주요 메소드
sleep() - 스레드 일시정지
yield() - 다른 스레드에게 자원사용을 양보
join() - 다른 스레드의 작업이 종료될 때까지 대기한 후 실행
wait(), notify() - 스레드 2개를 번갈아가며 실행
interrupt() - 스레드를 강제로 종료
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스레드가 동시처리 안하고 순차적인 실행을 하게 됨
- 부모클래스가 있을 땐 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);
}
}
}