19.04.16 멀티 스레드
Back-End/Java 2019. 4. 16. 13:48-멀티 스레드-
애플리케이션 내부의 멀티 태스킹 즉 프로세스 내부에서 두 가지 작업을 동시에 실행하는것.
멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를
발생시키면 프로세스 자체가 종료될 수 있어 다른 스레드에게 영향을 미치게 된다.
-스레드의 구현과 실행-
1. Thread 클래스 상속
2. Runable 인터페이스 구현
-멀티 스레드 장,단점-
장점
-자원을 보다 효율적으로 사용할 수 있음
-작업이 분리되어 코드가 간결해 짐
단점
-교착상태가 발생하지 않도록 주의해야 한다.
- 예제 및 출력 결과 -
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 |
package com.hs.chap12;
public class BeepPrintExample extends Thread {
// 생성자 정의
public BeepPrintExample(String name) {
super(name);
}
// 현재 실행중인 스레드의 이름을 출력한다.
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
BeepPrintExample a0 = new BeepPrintExample("스레드 1");
BeepPrintExample a1 = new BeepPrintExample("스레드 2");
BeepPrintExample a2 = new BeepPrintExample("스레드 3");
a1.setName("스레드 50");
a0.start();
a1.start();
a2.start();
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
package com.hs.chap12;
public class MyThread extends Thread {
//생성자 추가
public MyThread (String name)
{
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
//현재 실행중인 스레드의 이름
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(1500); //실행을 멈추는 거기때문에 예외처리가 반드시 필요
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13 |
package com.hs.chap12;
public class ExternThread {
public static void main(String[] args) {
MyThread t1 = new MyThread("스레드1");
MyThread t2 = new MyThread("스레드2");
t1.start();
t2.start();
}
}
|
cs |
-스레드의 이름-
Thread 클래스의 setName()메소드로 스레드의 이름을 변경
Thread 클래스의 getName()메소드로 스레드의 이름을 알수 있다.
-스레드 우선순위-
동시성: 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질
병렬성: 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질
스레드 스케줄링 : 스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해
동시에 실행할 것인가를 결정
(짧은 시간에 번갈아가면서 run() 메소드를 조금씩 실행함)
-동기화 메소드 및 동기화 블록-
임계 영역 = 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역, 임계 영역을
지정하기 위해 동기화 메소드와 동기화 블록을 제공한다.
형식 : 메소드선언에 synchronized 키워드를 붙이면 된다.
-스레드 상태-
실행 대기 상태 : 스케줄링이 되지 않아서 실행을 기다리고 있는 상태
실행 상태 : 실행 대기 상태에 있는 스레드 중에서 선택된 스레드가 run() 메소드를 실행한 상태
실행 종료 상태 : 실행 상태에서 run() 메소드가 종료되면 스레드의 실행이 멈추게 되는 상태
-스레드 상태 확인-
getState() 메소드는 스레드 상태에 따라서 Thread.State 열거 상수를 리턴한다.
-Thread 클래스 메소드-
sleep() : 주어진 시간동안 일시 정지
yield() : 다른 스레드에게 실행 양보
join() : 다른 스레드의 종료를 기다림
notify() : 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만듬
-데몬 스레드-
주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다.
주의할 점은 start() 메소드가 호출되고 나서 setDaemon(true)를 호출하면 예외가 발생하기 때문에
start() 메소드 호출 전에 setDaemon(true)를 호출해야 한다.
-스레드 그룹-
관련된 스레드를 묶어서 관리하는 것
스레드 그룹을 생성하는 방법은 다음 생성자 중 하나를 이용해서 스레드그룹 객체를 만들면 된다.
ThreadGroup tg = new ThreadGroup(String name);
ThreadGroup tg = new ThreadGroup(ThreadGroup parent, String name);
-예제 및 출력 결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
package synchronization;
public class WorkThread extends Thread {
public WorkThread(ThreadGroup threadGroup, String threadName) {
super(threadGroup, threadName);
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(getName() + "interrupted");
break;
}
}
System.out.println(getName() + "종료됨");
}
}
|
cs |
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 |
package synchronization;
public class ThreadGroupExample {
public static void main(String[] args) {
ThreadGroup myGroup = new ThreadGroup("myGroup");
WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
workThreadA.start();
workThreadB.start();
System.out.println("[main 스레드 그룹의 list()메소드 출력 내용]");
ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
mainGroup.list();
System.out.println();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("[myGroup 스레드 그룹의 interrupt()메소드 호출]");
myGroup.interrupt();
}
}
|
cs |
-스레드풀-
작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가
맡아 처리한다.
java.util.concurrent 패키지에서 ExecutorService 인터페이스와 ExecutorService 구현 객체를 만들 수 있는데, 이것이 바로 스레드풀이다.
-작업 생성-
하나의 작업은 Runnable 또는 Callable 구현 클래스로 표현한다.
Runnable과 Callable의 차이점은 작업 처리 완료 후 리턴값의 유무이다.
Runnable의 run() 메소드는 리턴값이 없고, Callable의 call() 메소드는 리턴값이 있다.
-작업 처리 요청-
ExecutorService의 작업 큐에 Runnable 또는 Callable 객체를 넣는 행위를 말한다.
-중요 예제-
'Back-End > Java' 카테고리의 다른 글
19.04.18 람다식 (0) | 2019.04.18 |
---|---|
19.04.17 제네릭,와일드카드 (0) | 2019.04.17 |
19.04.15 String클래스 메소드, 정규 표현식, 배열정렬 및 검색, 박싱,언박싱 (0) | 2019.04.15 |
19.04.14 객체 소멸자, 객체 비교, 동등 비교 등 (0) | 2019.04.14 |
19.04.12 API, java.lang / java.util 패키지, 해시코드 (0) | 2019.04.12 |