hyeonga_code
Java_59_API_스레드_생명 주기, 멀티 스레드, 메소드, 스레드 종류, 스케줄링 방식, 스레드 스케줄러, 동기화 본문
- Thread_스레드
- 생명 주기
- NEW : 스레드가 만들어진 상태
- Runnable : 스레드 객체가 생성된 후에 start() 메소드 호출 시 이동합니다.
- Running : Runnable 상태에서 스레드 스케줄러에 의해 이동합니다.
- Blocked : 스레드가 다른 특정한 이유로 Running 상태에서 Blocked 상태로 이동합니다.
- Dead : 스레드 종료 시 다시 시작할 수 없습니다.
- 멀티 스레드
- 하나의 프로그램 안에서 여러 개의 프로그램을 동시에 실행하도록 하는 것
- 프로세스 내에서 실행되는 세부 작업 단위입니다.
- 멀티 프로세스 : 두 개 이상의 프로세스가 실행되는 것
- 멀티 태스킹 : 두 개 이상의 프로세스를 실행하여 일을 처리하는 것
- 방법
- Thread 클래스 상속
- run 메소드를 오버라이드
- start 메소드를 실행
- 생성자
Thread()
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(String name)
- 순서
1. Runnable 인터페이스 상속
2. run 메소드를 오버라이드
3. Thread 클래스 객체를 생성하는 데 그 때 매개 변수로 넣음
4. 새로 만든 Thread클래스의 start를 해주면 된다
- 메소드
- sleep(long millis) : millis에 지정된 시간만큼 대기
- getName : 스레드 이름 반환
- setName(String name) : 스레드 이름 반환
- start() : 스레드 시작
- getPriority() : 스레드의 우선순위 반환
- setPriority(int newPriority) : 스레드 우선순위 지정
- join() : 현재 스레드는 join() 메소드를 호출한 스레드가 종료될 때까지 대기
- yield() : 수행중인 스레드 중 우선순위가 같은 다른 스레드에게 제어권을 넘김
- currentThread() : 현재 수행되는 스레드 객체를 리턴합니다.
- 스레드 종류
- User Thread
- main()의 종료와 상관없이 thread는 계속 실행됩니다.
- setDaemon(false)
- Daemon Thread
- main()의 종료 시 thread가 종료됩니다.
- setDaemon(true)
- 스케줄링 방식
- 선점형 스레드 스케줄링
- 스레드의 우선권을 가지고 우선 순위가 높은 스레드를 먼저 수행시키는 방식
- 협력형 스레드 스케줄링
- 실행중인 스레드가 CPU 사용권을 다른 스레드에게 넘길 때까지 기다리는 방식
- JVM
- 우선 순위에 따른 선점형 스레드 스케줄링 방식을 사용합니다.
- SJF_Shortest Job First
- 스레드 스케줄러
- 멀티 스레드가 수행될 때 어떤 스레드가 먼저 수행될지는 스케줄러가 결정합니다.
- 자바 애플리케이션에서는 우선 순위가 높은 선점형 스레드 스케줄러를 사용합니다.
- Thead에 관한 정보 알아내기
- 우선순위 결정(1-10)
setPriority(MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY)
- main() 연관성
setDaemon(true/false)
- 반드시 start 이전에 설정해야 합니다.
Thread[] th = new Thread('개수');
Thread.enumerate(th); // Thread의 정보를 저장
- 동기화
- 동시 접근을 방지합니다.
- 임계영역 : 멀티 스레드에의해 공유 자원이 참조될 수 있는 코드의 범위
- 멀티 스레드 프로그램에서 임계영역을 처리하는 경우 심각한 문제가 발생할 수 있습니다.
- 동기화를 처리하기 위해 모든 객체에 락_lock을 포함했습니다.
- lock
- 공유 객체에 여러 스레드가 동시에 접근하지 못하도록 하기 위함입니다.
- 모든 객체가 힙 영역에 생성될 때 자동으로 생성됩니다.
- 잘못 동기화 시키는 경우 Dead Lock 이 걸립니다.
- 동기화 방법
public synchronized void synchonizedMethod(){
// 임계 영역 코딩
}
public void nomalMethod(){
synchronized(동기화할 객체/클래스 이름){
// 임계영역 코딩
}
}
- 관련 용어
- Fairness_공정
- 여러 스레드가 하나의 컴퓨팅 자원을 사용하기 위해 동시에 접근하는 프로그램을 작성하는 경우
- 모든 스레드는 공정하게 그 자원을 사용할 수 있습니다.
- Starvation_기아
- 하나 또는 그 이상의 스레드가 자원을 얻기 위해 Blocked 상태에 위치
- 자원을 얻을 수 없게 되면 다른 작업을 할 수 없습니다.
- Deadlock_교착 상태
- 두 개 이상의 스레드가 만족하지 못하는 상태로 계속 기다리는 경우 발생합니다.
- Thread 클래스 상속
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
class MyThread05 extends Thread{
public void run() {
System.out.println("Run");
}
}
public class ex0325 {
public static void main(String[] args) {
System.out.println("Run Main Class");
MyThread05 th = new MyThread05();
//th.run; // 단일 스레드
th.start();
// 멀티 스레드
System.out.println("End Main Class");
// Thread를 상속받은 객체를 새로운 스레드 영역에서 run 메소드를 실행
/*
Run Main Class
End Main Class
Run
*/
}
}
|
- Runnable
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
class MyThread06 implements Runnable {
public void run() {
System.out.println("Running MyThread06");
}
}
public class ex0325 {
public static void main(String[] args) {
System.out.println("Run Main Class");
MyThread06 mth = new MyThread06();
Thread th2 = new Thread(mth);
// Runnable을 상속받은 클래스는 start 메소드가 없음
// Thread 클래스 객체를 생성할 때 Runnable 타입의 객체를 받아 Thread 객체를 만들 수 있음
// 새로운 Thread 클래스를 선언, 새로운 Thread 클래스의 start 메소드를 실행하면
// Runnable을 상속받아 만든 클래스의 run 메소드를 새로운 Thread 영역에서 실행시킨다.
th2.start();
/*
Run Main Class
Running MyThread06
*/
}
}
|
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.util.*;
class MyThread extends Thread{
public void run() {
System.out.println("Info: " + MyThread.currentThread());
}
}
public class ex0325 {
public static void main(String[] args) {
MyThread th = new MyThread();
th.start();
System.out.println(Thread.currentThread());
/*
Thread[main,5,main]
Info: Thread[Thread-0,5,main]
*/
}
}
|
=====
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
|
import java.util.*;
import java.text.*;
class MyThread extends Thread {
private Date date;
private SimpleDateFormat sdf;
public MyThread() {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
public void run() {
//System.out.println("정보 : " + Thread.currentThread());
while (true) {
date = new Date();
System.out.println("현재시각 : " + sdf.format(date));
try {
Thread.sleep(1000); //밀리세컨드 단위로 숫자를 넣어준다
}
catch (InterruptedException e) {}
}
}
}
public class Exam_06 {
public static void main(String[] args) {
MyThread th = new MyThread();
th.setDaemon(true); //main이 끝나면 th객체는 끝난다
//\th.setName("홍길동");
//th.setPriority(10);
//priority : 1~10 -> 1이 제일 느림, 10이 제일 빠름, 5가 default
th.start();
try {
Thread.sleep(5000); //밀리세컨드 단위로 숫자를 넣어준다
th.join(5000); //th객체를 5초간 실행시켜주세요
}
catch (InterruptedException e) {}
//System.out.println(Thread.currentThread());
}
}
|
join
=====
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
|
package com.java.exam04;
class MyRunnableTwo implements Runnable {
public void run() {
System.out.println("run");
first();
}
public void first() {
System.out.println("first");
second();
}
public void second() {
System.out.println("second");
}
}
public class JoinEx {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + " start");
Runnable r = new MyRunnableTwo();
Thread myThread = new Thread(r);
myThread.start();
try {
myThread.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end");
/*
main start
run
first
second
main end
*/
}
/** myThread가 멈출때까지 기다립니다.
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + " start");
Runnable r = new MyRunnableTwo();
Thread myThread = new Thread(r);
myThread.start();
// try {
// myThread.join();
// } catch (InterruptedException ie) {
// ie.printStackTrace();
// }
System.out.println(Thread.currentThread().getName() + " end");
/
main start
main end
run
first
second
/
}
*/
}
|
- 업다운 게임, 소요시간 알림
=====
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
|
import java.util.*;
class UpDownGame extends Thread{
private int comsu;
private Scanner in;
private int time;
private boolean isGame;
public UpDownGame() {
in = new Scanner(System.in);
comsu = (int)(Math.random()*100) + 1;
time = 0;
isGame = true;
}
public void run() {
while(isGame) {
time++;
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
}
public void gameStart() {
this.start();
while(true) {
System.out.print("수를 입력 : ");
int su = in.nextInt();
if (su == comsu) {
break;
}else if (su < comsu) {
System.out.println("Up");
}else {
System.out.println("Down");
}
}
isGame = false;
System.out.println(time+"초만에 맞추셨습니다.");
}
}
public class Exam_07 {
public static void main(String[] args) {
UpDownGame game = new UpDownGame();
//game.start();
game.gameStart();
}
}
|
'Java' 카테고리의 다른 글
Java_61_Math 클래스, Math.random(), 업다운 게임 (0) | 2023.10.25 |
---|---|
Java_60_API_스트링 버퍼, 스트링 빌더_StringBuffer, String Builder (0) | 2023.10.24 |
Java_58_API_lang 패키지, Object 클래스 메소드, String, 메소드 체인 (0) | 2023.10.24 |
Java_57_Log_로그 처리 (0) | 2023.10.17 |
Java_56_예외 처리 (0) | 2023.10.16 |