프로세스 : 실행중인 애플리케이션
스레드 : 프로세스 내에서 실제로 작업을 수행하는 주체
- 싱글 스레드 : 순차처리
- 멀티 스레드(스레드 n개) :
- 1개(코어)가 번갈아가면서 처리 → 동시성 Concurrency
- 여러개 스레드가 각각 처리 → 병렬성 Parallelism
스레드 생성방법
자바에서는 스레드도 클래스로 구현되어 객체로 사용되며, run() 메서드 내에 스레드가 처리할 작업을 작성
스레드 실행 시 .start() (.run()아님)
1. Runnable 인터페이스를 구현한 클래스에 run()을 정의
Thread 객체를 생성하고 사용(파라미터로 run() 메서드객체)
2. Thread클래스를 상속 받은 하위 클래스에서 run()을 정의
단일 상속으로 다른 클래스 상속이 필요할 경우 사용성 제한됨
// run() 메서드 정의
//1. interface 구현
class RunnableTsk implements Runnable{
@Override
public void run(){
//스레드 할일 정의
for(int i = 0; i<100; i++) Sy stem.out.print("RUN");
}
}
//2. Thread 상속
class subTreadTask extends Thread{
@Override
public void run(){
//스레드 할일 정의
for(int i = 0; i<100; i++) System.out.print("SUB");
}
}
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new RunnableTsk()); //1
Thread thread2 = new subTreadTask(); //2
thread1.start();
thread2.start();
}
}
3. 익명객체 사용
public class ThreadExample1 {
public static void main(String[] args) {
// 익명 Runnable 구현 객체를 활용하여 스레드 생성
Thread thread1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) System.out.print("#");
}
});
// 익명 Thread 하위 객체를 활용한 스레드 생성
Thread thread2 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) System.out.print("@");
}
};
thread2.start();
thread1.start();
}
}
→ 1,3 방법으로 많이 사용
스레드 정보 조회
Thread.currentThread().getName() //현재 thread 이름조회
// 스레드의_참조값.getName()
Thread thread3 = new ~~~
thread3.getName();
thread4.setName("스레드 이름 설정");
스레드 대기
- thread1.join(밀리초) : 해당 스레드가 동작하는 동안 메인 스레드가 기다림(파라미터 없으면 종료될때까지)
- Thread.sleep(밀리초) : 해당 스레드가 동작을 멈추고(일시정지) 기다림. 다른 스레드가 실행됨.
Thread thread1 = new Thread(new RunnableTsk())
thread.start();
try {
thread1.join(2500); // 2.5 초 대기
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
스레드 동기화 (Synchronization)
1개의 객체에 스레드가 동시에 접근하면서 문제가 발생함
따라서, 공유객체에 접근하는 순간은 싱글 스레드로 동작하도록 해야 함
- 임계영역(Critical section)과 락(Lock)
- 임계영역 : 코드 영역의 일부를 한번에 한개의 스레드만 실행하도록 함
- 락 : 그 임계영역에 들어갈 수 있는 접근권한
- 임계영역 지정방법
- 동기화 메서드 (메서드 전체를 임계영역으로 만들어 줌) : 반환타입 앞에 synchronized
- 동기화 블럭 : 특정부분만 지정 : synchronized(공유객체ex this){}
public synchronized boolean withdraw(int money) {...} //1. 메서드 전체 public boolean withdraw(int money) { synchronized (this) { ...} //2. 일부 영역 ...}
스레드 풀 Thread Pool
스레드를 만들어서 사용하는 것은 cpu입장에서 비용이 많이드는 일임(컴퓨터 성능 저하)
꼭 필요한 일이 아니면 멀티스레드를 안만들어도 됨
스레드를 만드는게 아니라, 스레드 풀에 작업을 요청함
- 요청받고
- 필요에 따라 생성하고 최대갯수 제한해줌
- 스레드 재활용도 해줌
스레드 풀 내에 > 작업 대기줄(작업 큐) > 순차적으로 작업 요청이 옴
스레드풀 → 객체 ExecutorService 구현 객체
ExecutorService threadPool = Executors.newFixedThreadPool(2);
threadPool.execute(new RunnableTask1());
threadPool.execute(new RunnableTask2());
threadPool.shutdown();
'Coding > 언어-JAVA' 카테고리의 다른 글
JAVA Q&A (0) | 2023.08.17 |
---|---|
JAVA 메서드 활용 (0) | 2023.08.17 |
JAVA 파일입출력(File I/O) #Day9 (0) | 2023.08.17 |
JAVA 사용자 입출력(Scanner, Printf) (0) | 2023.08.17 |
JAVA 스트림(Stream) #Day8 (0) | 2023.08.16 |