본문 바로가기

Java

자바 멀티 스레드 프로그래밍

기본적으로 자주 사용하는 스프링도 멀티 스레드 프로그램이다.

 

멀티 스레드와 싱글 스레드의 성능의 차이를 테스트 해볼 예정입니다.

자바에서 멀티 스레드 환경 프로그래밍을 하기 위해 Thread클래스와,  Runable 인터페이스가 존재합니다.

Runable 인터페이스 같은 경우 다른 클래스를 상속받을 수 있기 때문에 상속이 필요한 경우 사용합니다.

 

테스트에 사용할 로직은 단순한 소수 개수를 구하는 로직입니다.

싱글 스레드 환경 테스트 로직

package Thread;

public class SingleThread {
	
	public static void main(String[] args) {
		SingleThread main = new SingleThread();
		long startTime = System.currentTimeMillis();
		int testRange = 100000;
		int count = 0;
		for(int i = 2; i <= testRange; i ++) {
			boolean test = main.isPrimeNum(i);
			if(test == true) {
				count ++;
			}
		}
		System.out.println("소수 갯 수 : "+ count);
		long endTime = System.currentTimeMillis();
		long diffTime = endTime - startTime;
		System.out.println("총 걸린 시간 :" +diffTime);
	}
	
	boolean isPrimeNum(int cnt) {
    	//홀수와 짝수의 차이를 줄이기 위해 바로 리턴 시키지 않음
		boolean flag = true;
		for(int i = 2; i < cnt; i ++) {
			int test = cnt % i;
			if(test == 0) {
				flag =  false;
			}
		}
		return flag;
	}
	
}

싱글 스레드 환경 테스트 결과

걸린 시간 약 7.7 초

멀티 스레드 환경 테스트 로직

MutliThreadMain.java

package Thread;

public class MultiThreadMain {

	public static void main(String[] args) {
		MultiThreadMain main = new MultiThreadMain();
		long startTime = System.currentTimeMillis();
		int testRange = 100000;
		int count = 0;
		Worker worker = new Worker();
		// 홀 수 일 때 실행
		worker.start();
		// 짝 수 일때 로직
		for(int i = 2; i <= testRange; i ++) {
			if(i % 2 == 0) {
//				System.out.println(i);
				boolean test = main.isPrimeNum(i);
				if(test == true) {
					count ++;
				}
			}
		}
		try {
			worker.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int workerCount = worker.count;
		count += workerCount;
		System.out.println("소수 갯 수 : "+ count);
		long endTime = System.currentTimeMillis();
		long diffTime = endTime - startTime;
		System.out.println("총 걸린 시간 :" +diffTime);
	}
	
	boolean isPrimeNum(int cnt) {
    	//홀수와 짝수의 차이를 줄이기 위해 바로 리턴 시키지 않음
		boolean flag = true;
		for(int i = 2; i < cnt; i ++) {
			int test = cnt % i;
			if(test == 0) {
				flag =  false;
			}
		}
		return flag;
	}
}

Worker.java

package Thread;

public class Worker extends Thread{
	int testRange = 100000;
	int count = 0;
	// 짝수 만 실행
	public void run() {
		Worker worker = new Worker();
		for(int i = 2; i <= testRange; i ++) {
			if(i % 2 != 0) {
				boolean test = worker.isPrimeNum(i);
				if(test == true) {
					this.count ++;
				}
			}
		}
	}
	
	boolean isPrimeNum(int cnt) {
    	//홀수와 짝수의 차이를 줄이기 위해 바로 리턴 시키지 않음
		boolean flag = true;
		for(int i = 2; i < cnt; i ++) {
			int test = cnt % i;
			if(test == 0) {
				flag = false;
			}
		}
		return flag;
	}
}

멀티 스레드 환경 테스트 결과

약 4.2초

성능이 절반으로 떨어지면 좋겠지만 아쉽게도 그렇지는 않습니다.

왜냐하면 cpu 자원 할당과 같은 일들이 추가적으로 들어가야 하기 때문에 절반으로 줄어들지는 않습니다.

멀티 스레드의 경우 싱글스레드 보다 고려해야 할 것들이 많고, 고려해야 할 것이 많다는 이야기는 프로그래밍 난이도가 더 높다는 의미가 되며 상황에 따라 멀티 스레드 환경을 구축 해야 할 것 입니다.