스레드란
일반적인 자바 프로그램을 실행하면 작성한 코드가 위에서부터 아래로 순차적으로 실행합니다.
이러한 흐름을 하나의 스레드라고 표현합니다.
따라서 자바를 실행하면 "하나의 스레드가 실행되었다." 라고 표현할 수 있습니다.
그러나 대규모 프로그램의 경우 하나의 스레드로만 구현할 수 없는 경우가 많이 있습니다.
이런경우 다중스레드로 구현하면 각각의 스레드가 동시에 수행되면서 프로그램을 병렬처리 할 수 있습니다.
스레드 기동
스레드를 기동하기 위해서는 먼저 클래스 라이브러리의 Thread 클래스를 상속받아야 합니다.
상속받은 자식클래스는 반드시 run( ) 메소드를 작성해야 합니다.
run( ) 안에 작성된 코드는 일반적인 흐름과 달리 병렬로 동작하며 run ( ) 메소드가 시작점이 됩니다.
1
2
3
4
5
|
class thread1 extends Thread {
public void run () {
// .. 병렬처리 할 코드 구현
}
}
|
cs |
이 클래스를 실행하기 위해서는, 객체를 생성한 후 start ( ) 메소드를 호출해야 합니다.
1
2
3
4
5
6
7
8
|
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 th = new thread1();
th.start();
}
}
|
cs |
여러개의 스레드 기동
여러개의 스레드 기동을 원하는 경우, 객체를 더 생성 후 스레드를 실행해 주면 됩니다.
이렇게 구현하게 되면 6 라인에서 thread1 클래스의 스레드 하나를 생성하여 run 메소드를 실행합니다.
여기서 6라인 로직이 전부 끝난 후 다음단계로 넘어가는 게 아닌, 바로 8 라인으로 넘어가게 됩니다.
다시 9 라인에서 thread1 클래스의 스레드 하나가 더 생성되고 run 메소드가 실행됩니다.
1
2
3
4
5
6
7
8
9
10
11
|
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 th = new thread1();
th.start();
thread1 th2 = new thread1();
th2.start();
}
}
|
cs |
스레드 일시정지
그렇다면 스레드를 일시정지 하는 방법도 있어야 하겠죠?
Thread 클래스의 메소드인 sleep ( ) 함수를 사용하여 일시정지를 구현할 수 있습니다.
sleep 함수는 ( ) 안에 기입한 밀리단위 숫자 만큼 대기합니다. ( 1000 = 1초 )
sleep 함수를 사용하기 위해서는 try catch 문 안에 작성해 주어야 합니다.
1
2
3
4
5
6
7
8
9
10
11
|
class thread1 extends Thread {
public void run () {
// .. 병렬처리 할 코드 구현
try {
sleep (1000); // 1초 대기
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
cs |
경고 : 스레드 일시정지 기능을 하지 않았을 때
스레드를 구현할 때는 무한루프를 돌리며 주기적으로 문제가 없는지 확인을 위해서 사용되는 경우도 많습니다.
이 때 sleep 함수가 없으면, CPU 가 쉬지못하고 계속 확인을 하기 때문에 CPU 가 100% 로 증가하는 문제가 발생합니다.
sleep 함수를 꼭 사용하여 CPU 이슈를 방지해 주세요.
스레드 종료 대기
각각의 스레드는 전혀 다른 처리 흐름에서 동작합니다.
그러나 다른 스레드의 종료를 기다린 후 다시 동작하도록 하는 기능도 필요합니다.
이런 경우 Thread 클래스의 메소드인 join ( ) 함수를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 th = new thread1();
th.start();
thread1 th2 = new thread1();
try {
th.join();
} catch (Exception e) {
e.printStackTrace();
}
th2.start();
}
}
|
cs |
종료 대기 사용 예제
join 함수는 언제 사용될까요?
예를들면 1~1000까지 main 함수 내에서 더하기를 진행 후 작업이 완료되면 완료되었다는 결과를 출력합니다.
이를 3개의 스레드로 범위를 나눈 후 각각의 흐름에서 처리를 진행하도록 변경했습니다.
스레드로 동작하기 때문에 대기가 없다면 스레드 작업이 완료가 안되었음에도 다음 처리를 진행하게 됩니다.
스레드 예제
아래 조건을 만족하며 스레드를 구현해 봅니다.
1. run 메소드는 1초씩 대기를 해야 합니다.
2. 1 ~ 10 까지 3개의 스레드로 나눠서 더하기를 진행합니다.
3. 3개 스레드 작업이 완료되면 최종 더한 값과 작업이 완료되었다는 결과를 출력합니다.
코드에서 자세한 내용은 생략하도록 하겠습니다.
분석하시고 이해하시면 충분히 도움되실 수 있을 것으로 보입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
public class ThreadTest {
static int num;
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 th = new thread1(1, 1, 3);
thread1 th2 = new thread1(2, 4, 6);
thread1 th3 = new thread1(3, 7, 10);
th.start();
th2.start();
th3.start();
try {
th.join();
th2.join();
th3.join();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("더하기 작업이 완료되었습니다. 모든 수를 더한 값은 " + th.getAddNum() + " 입니다.");
}
}
class thread1 extends Thread {
static int all_add_num = 0;
int add_num = 0;
int thread_num = 0;
int start = 0;
int end = 0;
thread1 ( int thread_num, int start, int end ) {
this.thread_num = thread_num;
this.start = start;
this.end = end;
}
public void run () {
try {
for ( int i = start ; i <= end ; i ++ ) {
System.out.println ( "쓰레드 ID " + this.thread_num + " :: i 값 : " + i );
add_num = add_num + i;
sleep (1000); // 1초 대기
}
} catch (Exception e) {
e.printStackTrace();
}
setTPS (add_num);
}
public void setTPS ( int num ) {
all_add_num = all_add_num + num;
}
public int getAddNum () {
return all_add_num;
}
}
|
cs |
스레드를 생성하는 또 다른 방법 Runnable
위에서는 스레드 클래스를 상속받는 방법으로 구현하였습니다.
그러나 이미 클래스가 다른 클래스를 상속받고 있으면 어떻게 해야할까요?
클래스는 2개의 클래스를 상속받을 수 없습니다.
이런 경우 Runnable 인터페이스를 사용하여 클래스를 만들 수 있습니다.
즉, Thread 클래스를 사용하는게 아닌 Runnable 인터페이스를 구현하는 것 입니다.
단, 인터페이스 형식으로 작성하는 경우 추가로 해야할 내용이 있습니다.
주석을 확인해 주세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
thread1 runnable_th = new thread1();
Thread th = new Thread(runnable_th); // 클래스 객체 생성 후, 스레드 클래스에 생성한 객체를 등록해 주어야 합니다.
th.start();
}
}
class thread1 implements Runnable {
public void run () {
try {
Thread.sleep (1000); // 1초 대기 -> Runnable 로 구현한 경우 Thread 클래스를 명시해 주어야 합니다.
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
cs |
자바 스레드 생성
자바 스레드 일시정지
자바 스레드 실행
자바 스레드 예제
자바 스레드 상속
자바 스레드 Thread 상속
자바 스레드 Runnable 인터페이스
'Computer Language > JAVA' 카테고리의 다른 글
[JAVA] 자바 public static void main (String[] args) 의미 (8) | 2021.03.28 |
---|---|
[JAVA] 자바 스레드 synchronized 동기화 방법 (0) | 2021.03.26 |
[JAVA] 자바 예외처리 방법 try catch finally 문 (0) | 2021.03.17 |
[JAVA] 자바 임포트(import)란 (0) | 2021.03.16 |
[JAVA] 자바 패키지(Package)란? (0) | 2021.03.16 |