가자미의 개발이야기

[자바] 쓰레드를 생성하는 더 좋은 방법 본문

Java/자바 기본 문법

[자바] 쓰레드를 생성하는 더 좋은 방법

가자미 2021. 3. 2. 15:15

쓰레드 풀 모델 : 사용가능한 쓰레드들을 쓰레드 풀에 담아두고 작업에 따라 쓰레드를 할당.

(매 작업마다 쓰레드를 생성&소멸하면 리소스 낭비가 심각하기 때문.)

 

쓰레드 풀 활용 예시

class ExecutorsDemo{
	public static void main(String[] args) {
		Runnable task=()->{	//쓰레드에게 시킬 작업
			int n1 = 10;
			int n2 = 20;
			String name = Thread.currentThread().getName();
		};
		
		ExecutorService exr = Executors.newSingleThreadExecutor();//하나씩 쓰레드를 할당
		exr.submit(task);//쓰레드 풀에 작업 전달
		exr.shutdown();//쓰레드 풀과 그 안에 있는 쓰레드 소멸
	}
}

 

쓰레드 풀 유형

//newSingleThreadExecutor(); 1개의 쓰레드를 작업에 할당
//newFixedThreadPool(int n); n개의 쓰레드를 작업에 할당
//newCachedThreadPool(); 작업의 수에 따라 유동적으로 쓰레드 할당(비추천)
class ExecutorsDemo{
	public static void main(String[] args) {
		Runnable task1=()->{	//쓰레드에게 시킬 작업
			String name = Thread.currentThread().getName();
		};
		Runnable task2=()->{	//쓰레드에게 시킬 작업
			String name = Thread.currentThread().getName();
		};
		
		ExecutorService exr = Executors.newFixedThreadPool(3);//쓰레드풀에서 세개의 쓰레드를 호출
		exr.submit(task1);//쓰레드 풀에 작업 전달
		exr.submit(task2);//쓰레드 풀에 작업 전달
		exr.submit(()->{
			String name = Thread.currentThread().getName();
		});
		exr.shutdown();//쓰레드 풀과 그 안에 있는 쓰레드 소멸
	}
}

 

Collable <>인터페이스(call추상메소드)

Runnable인터페이스(run추상메소드)와 비슷.

하지만 Collable은 추상메소드의 반환형을 선택할 수 있음.

class ExecutorsDemo{
	public static void main(String[] args) {
		Callable<Integer> task=()->{
			int sum =0;
			for(int i=0;i<10;i++)
				sum+=i;
			return sum;
		};
		
		ExecutorService exr = Executors.newSingleThreadExecutor();
		Future<Integer> fur = exr.submit(task);
		
		Integer r = fur.get(); //쓰레드 반환값 획득
		exr.shutdown();
	}
}

 

synchronized를 대신하는 ReentrantLock

class Myclass{
	reentrantLock criticObj = new ReentrantLock();
    void myMethod(int arg){
    	criticObj.lock();	//잠근다.
        .....	//한 쓰레드에 의해서만 실행되는 영역
        criticObj.unlock();	//푼다.
 
 //바람직한 코드작성
 class Myclass{
	reentrantLock criticObj = new ReentrantLock();
    void myMethod(int arg){
    	criticObj.lock();	//잠근다.
        try{
        	........//한 쓰레드에 의해서만 실행되는 영역
        } finally{
        criticObj.unlock();	//푼다.
        }
   }
}