• 검색 결과가 없습니다.

스레드 스케줄링 학습

N/A
N/A
Protected

Academic year: 2022

Share " 스레드 스케줄링 학습 "

Copied!
33
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

스레드(Thread)

(2)

 멀티스레드와 멀티태스킹 차이 이해

 자바 가상 머신이 제공하는 스레드 모델 이해

 자바 스레드 구현법 실습

 스레드 스케줄링 학습

학습목표

 스레드 스케줄링 학습

 스레드 생명 주기 이해

 자바 스레드의 동기화와 통신 메커니즘 이해

(3)

 스레드

 하나의 프로그램에서 동시에 하나 이상이 실행

 메모리 자원을 절약할 수 있어 효율적

cf. 멀티태스킹여러 개의 프로그램이 동시에 실행

자바 언어는 스레드를 기본 패키지와 키워드에서 제공

스레드와 멀티스레드

 자바 언어는 스레드를 기본 패키지와 키워드에서 제공

 멀티스레드

 하나의 프로그램 내부에서 마치 두 개 이상의 프로그램 이 동작하는 것과 같은 기능

 병행 처리라고도 함.

(4)

스레드와 멀티스레드

 병행 처리

 한 개의 CPU가 동시에 실행 주기를 수행하는 것

 병렬 처리

 두개 이상의 CPU가 동시에 실행 주기를 수행하는 것

(5)

자바 스레드 관련 예제

public class Thread00 {

public static void main(String[] args) { // 스레드를 생성한다.

Thread thread = new Thread();

// 스레드를 시작한다.

thread.start();

} } }

아무런 내용이 표시되지 않는다.

결과

(6)

자바 스레드 관련 예제

public class Thread01 extends Thread { public void run()

{

for (int i = 0; i < 5; i++)

System.out.println("Thread 1:" + i);

}

public static void main(String[] args) { Thread 0:0 결과

 Thread 클래스를

상속해서 스레드 구현

public static void main(String[] args) { Thread thread = new Thread01();

thread.start();

for (int i = 0; i < 5; i++)

System.out.println("Thread 0:" + i);

} }

Thread 0:0 Thread 0:1 Thread 0:2 Thread 0:3 Thread 0:4 Thread 1:0 Thread 1:1 Thread 1:2 Thread 1:3 Thread 1:4

(7)

자바 스레드 관련 예제

public class Thread02 extends Thread { public void run()

{

for (int i = 0; i < 5; i++)

System.out.println("Thread 1:" + i);

}

Thread 1:0 결과

 run() 메소드 사용 예제

public static void main(String[] args) { Thread thread = new Thread02();

thread.run();

for (int i = 0; i < 5; i++)

System.out.println("Thread 0:" + i);

} }

Thread 1:0 Thread 1:1 Thread 1:2 Thread 1:3 Thread 1:4 Thread 0:0 Thread 0:1 Thread 0:2 Thread 0:3 Thread 0:4

(8)

자바 스레드 관련 예제

public class Thread03 extends Thread { public void run()

{

// sleep() 메소드는 try ... catch 예외 처리를 필요로 한다.

try {

for (int i = 0; i < 5; i++) {

System.out.println("Thread 1:" + i);

// 1초간 정지한다.

sleep(1000);

 sleep() 메소드 사용 예제

sleep(1000);

}

} catch (Exception e) {

e.printStackTrace();

} }

public static void main(String[] args) { Thread thread = new Thread03();

thread.start();

(9)

자바 스레드 관련 예제

// sleep() 메소드는 try ... catch 예외 처리를 필요로 한다.

try {

for (int i = 0; i < 5; i++) {

System.out.println("Thread 0:" + i);

// 1초간 정지한다.

Thread.sleep(1000);

}

} catch (Exception e) {

Thread 0:0 Thread 1:0 Thread 0:1 Thread 1:1 Thread 0:2

결과

{

e.printStackTrace();

} } }

Thread 0:2 Thread 1:2 Thread 0:3 Thread 1:3 Thread 0:4 Thread 1:4

(10)

자바 스레드 관련 예제

public class Thread04 implements Runnable { int i;

public Thread04() {

i = 0;

}

public void run()

 Runnable 인터페이스 구현

public void run() {

// sleep() 메소드는 try ... catch 예외 처리를 필요로 한다.

try {

while(i < 10) {

// Thread.currentThread()는 현재의 스레드를 얻는 메소드 // obj.getName()은 스레드의 이름을 얻는 메소드

System.out.println(Thread.currentThread().getName() + ":" + i);

i++;

(11)

자바 스레드 관련 예제

// 1초간 정지한다.

Thread.sleep(1000);

}

} catch (Exception e) {

e.printStackTrace();

}

} Thread-0:0

결과 }

public static void main(String[] args) { Thread04 ex = new Thread04();

Thread thread0 = new Thread(ex);

thread0.start();

Thread thread1 = new Thread(ex);

thread1.start();

}

Thread-0:0 Thread-1:1 Thread-0:2 Thread-1:3 Thread-0:4 Thread-1:5 Thread-0:6 Thread-1:7 Thread-0:8 Thread-1:9

(12)

자바 스레드 관련 예제

public class Thread05 implements Runnable { int i;

public Thread05() {

i = 0;

}

public void run()

 스레드 이름을 정의할 수 있도록 수정한 예제

public void run() {

String name;

// sleep() 메소드는 try ... catch 예외 처리를 필요로 한다.

try {

while(i < 10) {

// Thread.currentThread()는 현재의 스레드를 얻는 메소드 Thread thread = Thread.currentThread();

// thread.getName()은 스레드의 이름을 얻는 메소드 name = thread.getName();

System.out.println(name + ":" + i);

i++;

(13)

자바 스레드 관련 예제

// 1초간 정지한다.

Thread.sleep(1000);

}

} catch (Exception e) {

e.printStackTrace();

}

} 스레드0:0

결과

}

public static void main(String[] args) { Thread05 ex = new Thread05();

Thread thread0 = new Thread(ex, "스레드0");

thread0.start();

Thread thread1 = new Thread(ex, "스레드1");

thread1.start();

}

스레드0:0 스레드1:1 스레드0:2 스레드1:3 스레드0:4 스레드1:5 스레드0:6 스레드1:7 스레드0:8 스레드1:9

(14)

스레드 생명 주기

born

Thread 생성

start() 메소드 호출

sleep() 메소드 호출 wait() 메소드 호출

ready blocked

dead

wait() 메소드 호출 I/O 요청

sleep 시간 완료 notify() 메소드 호출

I/O 완료 run() 메소드 완료

(15)

스레드 생명주기: Ready 상태와 Blocked 상태의 전환

 ready 상태와 blocked 상태의 상호 전환 사유

ready 상태 -> blocked 상태 blocked 상태 -> ready 상태

객체의 wait() 메소드 호출 객체의 notify()/notifyAll() 메소드 호출 sleep() 메소드 호출 sleep() 상태가 종료되었을 경우

I/O 동작 수행 I/O 동작 완료

다른 스레드의 join() 메소드 호출

suspend() 메소드 호출(권장되지 않음) resume() 메소드 호출(권장되지 않음)

(16)

스레드 생명주기 관련 예제

public class Thread06 implements Runnable { public void run()

{

// 스레드로 동작 시작

System.out.println("Thread1 started.");

try {

// 5초간sleep

Thread.sleep(5000);

} catch (Exception e)

Thread1 created.

Thread1 started.

Thread1 ended.

Thread1 joined.

결과

 join() 메소드 이용 예제

// 스레드실행

thread.start();

} catch (Exception e) {

e.printStackTrace();

}

// 스레드종료 알림

System.out.println("Thread1 ended.");

}

public static void main(String[] args) { // Thread06 객체를

// Runnable 참조 변수로 저장 Runnable r = new Thread06();

// 스레드생성

Thread thread = new Thread(r);

thread.start();

// 스레드생성을 알림.

System.out.println("Thread1 created.");

try {

// 스레드 종료 시점까지 대기 thread.join();

System.out.println("Thread1 joined.");

} catch (Exception e) {

e.printStackTrace();

} } }

(17)

스레드 생명주기 관련 예제

 스레드 생성과 Join() 메소드

start()

쓰레드 생성 새 쓰레드

main() 쓰레드

start()

run() join()

쓰레드 종료 다음 실행

종료 대기 시간 t

(18)

스레드 생명주기 관련 예제

public class Thread07 implements Runnable { public void run()

{

// 스레드로 동작 시작

System.out.println("Thread1 started.");

try {

while(true) {

if (Thread.interrupted() == true) { System.out.println("Thread1 interrupted.");

 interrupt() 메소드 이용 예제

System.out.println("Thread1 interrupted.");

break;

} }

} catch (Exception e) {

e.printStackTrace();

}

// 스레드종료 알림

System.out.println("Thread1 ended.");

}

public static void main(String[] args) { // Thread07 객체를 Runnable 참조 변수로 저장 Runnable r = new Thread07();

(19)

스레드 생명주기 관련 예제

// 스레드생성 결과

Thread thread1 = new Thread(r);

// 스레드실행

thread1.start();

// 스레드생성을 알림.

System.out.println("Thread1 created.");

try {

// 1초간 대기

Thread.sleep(1000);

// Thread1의 인터럽트 여부 확인

Thread1 created.

Thread1 started.

interrupted() before interrupt() calling: false interrupted() after interrupt() calling: true Thread1 interrupted.

Thread1 ended.

Thread1 joined.

// Thread1의 인터럽트 여부 확인

System.out.println("Thread1.interrupted() before interrupt() calling: " + thread1.isInterrupted());

// Thread1의interrupt() 메소드 호출 thread1.interrupt();

// Thread1의 인터럽트 여부 확인

System.out.println("Thread1.interrupted() after interrupt() calling: " + thread1.isInterrupted());

// 스레드 종료 시점까지 대기 thread1.join();

System.out.println("thread1 joined.");

} catch (Exception e) {

e.printStackTrace();

} }

(20)

스레드 생명주기 관련 예제

 예제 Thread11.java 동작 다이어그램

쓰레드1 생성 main() 쓰레드

쓰레드1 생성 쓰레드1 start()

쓰레드1

쓰레드2

쓰레드2 start()

쓰레드 종료 yield()

run()

run()

쓰레드 종료 yeield()

(21)

스레드 생명주기 관련 예제

public class Thread11 implements Runnable { public void run()

{

// 현재 스레드를 구하여 thread 변수에 저장 Thread thread = Thread.currentThread();

// 현재 스레드의 이름을 구하여 지역 변수 name에 저장.

String name = thread.getName();

 yield() 메소드 이용 예제

String name = thread.getName();

int j = 5;

try {

// 총 5번의 반복 while(j-->0) {

i += i;

System.out.println(name + ": " + i);

// 다른스레드를 실행 Thread.yield();

}

} catch (Exception e)

(22)

스레드 생명주기 관련 예제 EX14_11.java

{

e.printStackTrace();

} }

private int i = 1;

public static void main(String[] args) { Runnable r = new Thread11();

결과 Thread1: 2 Thread2: 4 Thread1: 8 Thread2: 16 Thread1: 32 Runnable r = new Thread11();

// 2개의 스레드 생성

Thread thread1 = new Thread(r, "Thread1");

Thread thread2 = new Thread(r, "Thread2");

// 2개의 스레드 시작 thread1.start();

thread2.start();

} }

Thread1: 32 Thread2: 64 Thread1: 128 Thread2: 256 Thread1: 512 Thread2: 1024

(23)

스레드 우선순위

 스레드 우선순위

 getPriority() 메소드 : 현재 스레드 우선순위를 얻는 메 소드

 setPriority() 메소드: 현재의 스레드 우선순위 결정

 우선순위는 int 정수형

 우선순위 관련 상수

 Thread.MIN_PRIORITY

 Thread.NORM_PRIORITY

 Thread.MAX_PRIORITY

(24)

스레드 우선순위 관련 예제

public class Thread08 extends Thread {

public void run() {

System.out.println("Thread.MIN_PRIORITY: " + MIN_PRIORITY);

System.out.println("Thread.NORM_PRIORITY: " + NORM_PRIORITY);

System.out.println("Thread.MAX_PRIORITY: " + MAX_PRIORITY);

try {

// 스레드 시작을 출력

System.out.println("thread1 started.");

// 시작 시점의 우선순위 출력

System.out.println("thread1 priority at start: " + getPriority());

 우선순위 지정

우선순위 상수 사용 예제

System.out.println("thread1 priority at start: " + getPriority());

// 잠시 0.5초간 sleep sleep(500);

// 우선순위 2로 수정 setPriority(2);

// 현재의 우선순위 출력

System.out.println("thread1 priority in running: " + getPriority());

// 스레드 종료 확인

System.out.println("thread1 ended.");

} catch (Exception e) {

e.printStackTrace();

} }

public static void main(String[] args) { Thread thread0 = Thread.currentThread();

Thread thread1 = new Thread08();

(25)

스레드 우선순위 관련 예제 EX14_08.java

System.out.println("thread0 priority: " + thread0.getPriority());

System.out.println("thread1 priority: " + thread1.getPriority());

System.out.println("thread1 isAlive() before start(): " + thread1.isAlive());

thread1.start();

// 스레드1의 우선순위를 1로 수정 thread1.setPriority(1);

try {

// 0.1초간sleep Thread.sleep(100);

// 스레드1이 종료했는지 안 했는지 확인

System.out.println("thread1 isAlive() System.out.println("thread1 isAlive() after start(): " + thread1.isAlive());

// 1초간sleep

Thread.sleep(1000);

// 스레드1의 종료를 기다림 thread1.join();

// 스레드1이 종료했는지를 확인

System.out.println("thread1 isAlive() after joining: " + thread1.isAlive());

// 스레드1의 우선순위를 3으로 수정 thread1.setPriority(3);

} catch (Exception e) {

e.printStackTrace();

} }

결과

thread0 priority: 5 thread1 priority: 5

thread1 isAlive() before start(): false Thread.MIN_PRIORITY: 1

Thread.NORM_PRIORITY: 5 Thread.MAX_PRIORITY: 10 thread1 started.

thread1 priority at start: 1

thread1 isAlive() after start(): true thread1 priority in running: 2 thread1 ended.

thread1 isAlive() after joining: false java.lang.NullPointerException

at java.lang.Thread.setPriority(Unknown Source)

(26)

스레드 스케줄링

 스레드는 우선 순위 이외에도 데몬 스레드인지 아닌지 판단하는 플래그 속성을 갖고 있음

 데몬 스레드

 데몬 스레드

 서비스 스레드라고도 함.

 낮은 우선순위를 갖는 경우가 많음.

 대표적인 데몬 스레드는 가비지 컬렉터

(27)

스레드 우선순위 관련 예제

public class Thread09 implements Runnable { public void run()

{

Thread.currentThread().setDaemon(false);

}

public static void main(String[] args) { Runnable r = new Thread09();

Thread thread1 = new Thread(r, "EX14_09");

System.out.println("thread1.isDaemon() before setDaemon(): " +

 setDaemon() 메소드 사용 예제

System.out.println("thread1.isDaemon() before setDaemon(): " + thread1.isDaemon());

thread1.setDaemon(true);

System.out.println("thread1.isDaemon() after setDaemon(true): " + thread1.isDaemon());

thread1.start();

System.out.println("thread1.isDaemon() after start(): " + thread1.isDaemon());

} thread1.isDaemon() before setDaemon(): false

thread1.isDaemon() after setDaemon(true): true thread1.isDaemon() after start(): true

java.lang.IllegalThreadStateException

at java.lang.Thread.setDaemon(Unknown Source) at Thread09.run(Thread09.java:16)

결과

(28)

안전한 스레드 중지 관련 예제

public class Thread10 extends Thread { private boolean stop = false;

public void run() {

// 스레드가 동작했음을 출력

System.out.println("Thread1 is running.");

// stop이 true일때까지 무한 반복 while(!stop)

 중지 플래그를 이용한 예제

while(!stop) {

// 여기에 코드를 삽입함 }

System.out.println("Thread1 is dead.");

}

public void setStop() {

stop = true;

}

public static void main(String[] args) { Thread10 thread1 = new Thread10();

(29)

안전한 스레드 중지 관련 예제 EX14_10.java

try {

// 스레드를 동작시킴 thread1.start();

System.out.println("Thread1 started.");

// .5초간sleep

Thread.sleep(500);

// setStop() 메소드 호출 thread1.setStop();

Thread1 started.

Thread1 is running.

Thread1.setStop() called.

Thread1 is dead.

Thread1 joined.

결과

thread1.setStop();

System.out.println("Thread1.setStop() called.");

// 스레드 종료를 기다림 thread1.join();

System.out.println("Thread1 joined.");

} catch (Exception e) {

e.printStackTrace();

} }

}

(30)

스레드 관리

 스레드 관리

 지역 변수를 제외한 모든 데이터와 메소드 공유 가능

 다만 공유할 경우, 공유 변수를 여러 스레드 사이에서 단 하나의 스레드에게만 사용 권한을 주는 것이 안전 단 하나의 스레드에게만 사용 권한을 주는 것이 안전

 원자 코드

 다른 스레드에 의해서 인터럽트될 수 없는 코드

 키워드 synchronized

 자바 언어에서 원자 코드와 유사한 기능 수행

(31)

스레드 관리 관련 예제

public class Thread13 implements Runnable { int money_in_bank = 100000000;

public void run() {

int money_need = 60000000;

int money = 0;

String msg = null;

try {

 키워드 Synchronized를 이용한 예제

try {

synchronized (this) {

if (getMoney() > money_need) { Thread.yield();

money = drawMoney(money_need);

msg = "인출 성공";

} else {

money = 0;

msg = "인출 실패";

} }

System.out.println(msg + ", 인출금액: " + money + ", 잔고: " + getMoney());

(32)

스레드 관리 관련 예제

} catch (Exception e) {

e.printStackTrace();

} }

private int getMoney() {

return money_in_bank;

}

private int drawMoney(int m) private int drawMoney(int m) {

money_in_bank -= m;

return m;

}

public static void main(String[] args) { Runnable r = new Thread13();

Thread thread1 = new Thread(r);

Thread thread2 = new Thread(r);

thread1.start();

thread2.start();

} }

인출 실패, 인출금액: 0, 잔고: 40000000

인출 성공, 인출금액: 60000000, 잔고: 40000000 결과

(33)

스레드간 통신

 스레드간 통신

 동기화된 코드를 실행하고 빠져 나오는 것에 대해 다 른 대기 스레드에게 알려주는 것

 자바 언어는 스레드 간의 통신을 위해 대기/공지

 자바 언어는 스레드 간의 통신을 위해 대기/공지 (wait/notify) 방식을 이용

 스레드간 통신 관련 메소드

 wait() 메소드

 notify()/notifyall() 메소드

참조

관련 문서

byte nextByte() 다음 아이템을 찾아 byte로 변환하여 반환 double nextDouble() 다음 아이템을 찾아 double로 변환하여 반환 float nextFloat() 다음 아이템을 찾아

[r]

– 컴퓨터에 기반한 교수 학습 환경은 수학적 대상과 관계의 형식적 표현을 다룰 수 있다는 점과 학습자와 컴퓨터의 상호작용을 함으 컴퓨터에 기반한 교수 학습

토끼를 무서워하는 아이에게 멀리서 토끼를 보면서 좋아하는 우유 와 쿠키를 먹게 하는 것,

본래의 이름을 잊어버려 자신의 세계로 돌아갈 수 없지만, 이름을 기억하는 것이 어떠한 의미를 지 니고 있는지를 정확히 파악하고 있는 그는 센에게

즉, &lt;FRAME&gt; 태그의 name 속성을 이용하여 프레임의 이름을 지정하고, &lt;A&gt; 태그의 target 속성에 그 이름을 지정하면 지정된

최종으로

™ 선언된 이름의 바인딩 정보를