Coding/언어-JAVA

JAVA 스레드(Thread) #Day10

꿀딴지- 2023. 8. 17. 14:05

프로세스 : 실행중인 애플리케이션

스레드 : 프로세스 내에서 실제로 작업을 수행하는 주체

  • 싱글 스레드 : 순차처리
  • 멀티 스레드(스레드 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입장에서 비용이 많이드는 일임(컴퓨터 성능 저하)

꼭 필요한 일이 아니면 멀티스레드를 안만들어도 됨

스레드를 만드는게 아니라, 스레드 풀에 작업을 요청함

  1. 요청받고
  2. 필요에 따라 생성하고 최대갯수 제한해줌
  3. 스레드 재활용도 해줌

스레드 풀 내에 > 작업 대기줄(작업 큐) > 순차적으로 작업 요청이 옴

스레드풀 → 객체 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