싱글쓰레드와 멀티쓰레드
두 개의 쓰레드로 작업한 시간이 싱글쓰레드로 작업한 시간보다 더 걸리게 되는데 그 이유는 쓰레드간의 작업전환(context switching)에 시간이 걸리기 때문
-> 단순히 CPU만을 사용하는 계산작업은 오히려 멀티쓰레드보다 싱글쓰레드로 프로그램하는 것이 더 효율적!!
예제) ' - ' 를 출력하는 작업과 ' | '를 출력하는 작업을 하나의 쓰레드가 연속적으로 처리하는 시간을 측정하는 예제(싱글쓰레드 프로세스)
class Ex13_2 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
//1번 작업 수행
for(int i=0; i < 100; i++)
System.out.printf("%s", new String("-"));
System.out.println("소요시간1: " + (System.currentTimeMillis() - startTime));
//2번 작업 수행
for(int i=0; i < 100; i++)
System.out.printf("%s", new String("|"));
System.out.println("소요시간2: " + (System.currentTimeMillis() - startTime));
}
}
수행시간을 측정하기 쉽게 "-"대신 new String("-")를 사용해서 수행속도를 늦췄다.
<출력값>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------소요시간1: 115
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요시간2: 151
예제2) 예제1을 멀티쓰레드러 변형
class Ex13_3 {
public static long startTime = 0; // main 메서드 안에 있으면 ThreadEx4_1이 사용할 수 없음
public static void main(String[] args) {
ThreadEx4_1 th1 = new ThreadEx4_1(); // Thread를 상속한 ThreadEx4_1 객체 생성
th1.start();//2번 작업 수행
startTime = System.currentTimeMillis();
//1번 작업 수행
for(int i=0;i<100;i++)
System.out.printf("%s", new String("-"));
System.out.println("소요시간1: " + (System.currentTimeMillis() - startTime));
}
}
//2번 작업 수행
class ThreadEx4_1 extends Thread {
public void run() {
for(int i=0; i<100; i++)
System.out.printf("%s", new String("|"));
System.out.println("소요시간2: " + (System.currentTimeMillis()-Ex13_3.startTime));
}
}
<출력값>
----------||-------------------||||||||||||---||||||||---------------------|||------|||||||||||||----|-----||||||||||||||-----|||||||-------------------------------------------------------------------------------------------------------|||--||||-----|||--------------||----------------------------------------||||||||---------------------------------------------------------------||||||||||||||||||||||||||||||||||||||||||||||소요시간2: 107
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요시간2: 124
싱글쓰레드와 비교해서 번갈아가면서 실행 되었다.
싱글쓰레드보다 더 많이 시간이 걸린 이유: 쓰레드간의 작업전환시간이 소요(1), 한 쓰레드가 화면에 출력하고 있는 동안 다른 쓰레드는 출력이 끝나기를 기다리는 대기시간(2)
쓰레드의 I/O 블락킹(blocking)
- 입출력시 작업 중단 되는 것 -> I/O 블락킹
-> 만일 사용자로부터 입력 받는 작업과 화면에 출력하는 작업을 하나의 쓰레드로 처리한다면 첫 번째 그래프처럼 사용자가 입력을 마칠 때까지 아무 일도 하지 못하고 기다려야함!!!
-> 두개의 쓰레드로 처리하면 사용자의 입력을 기다리는 동안 다른 쓰레드가 작업을 처리할 수 있기 때문에 보다 효율적인 CPU 사용 가능!
예제1) 싱글쓰레드 프로세스로 다중작업을 처리(사용자에게 입력 + 숫자 카운트다운)
import javax.swing.JOptionPane;
public class Ex13_4 {
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("아무값이나 입력하세요.");
System.out.println("입력한신 값은 " + input + " 입니다.");
for(int i=10;i>0;i--) {
System.out.println(i);
try {
Thread.sleep(1000); // 1초간 시간을 지연한다.
} catch(Exception e) {}
}
}
}
sleep( )는 메서드 자체가 항상 exception을 throw하기 때문에 try-catch구문으로 예외처리를 해주었다!
sleep( )을 속도 조절을 위해서 사용!
-> 사용자가 입력을 마치기 전까지는 화면에 숫자가 출력되지 않다가 사용자가 입력을 마치면 화면에 숫자가 출력됨
예제2) 예제1을 멀티쓰레드 프로세스로 작업을 처리
import javax.swing.JOptionPane;
public class Ex13_5 {
public static void main(String[] args) {
ThreadEx5_1 t1 = new ThreadEx5_1(); // 카운트다운 for문 실행하는 ThreadEx5_1 객체 생성
t1.start(); // for문 실행
String input = JOptionPane.showInputDialog("아무값이나 입력하세요");
System.out.println("입력하신 값은 " + input + "입니다.");
}
}
class ThreadEx5_1 extends Thread {
public void run() {
for(int i=10;i>0;i--) {
System.out.println(i);
try {
Thread.sleep(1000); // 1초씩 출력 쉼
} catch (Exception e) {}
}
}
}
-> 입력하는 작업과 countdown 하는 작업이 분리되어 있어서 사용자가 입력을 하지 않아도 카운트다운이 출력된다.
<출력값>
10
9
8
7
입력하신 값은 123456입니다.
6
5
4
3
2
1
'멀티캠퍼스 풀스택 과정 > Java의 정석' 카테고리의 다른 글
자바의 정석10-4 데몬 쓰레드(daemon thread)와 쓰레드의 실행제어 (0) | 2022.01.13 |
---|---|
자바의 정석10-3 쓰레드의 우선순위와 쓰레드 그룹 (0) | 2022.01.13 |
자바의 정석10-1 프로세스와 쓰레드 (0) | 2022.01.12 |
자바의 정석9-4 애너테이션(annotation) (0) | 2022.01.12 |
자바의 정석9-3 열거형(enum) (0) | 2022.01.12 |