71
1/70 강강강강강 14 강 강강강강강 Multithreading

1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

Embed Size (px)

DESCRIPTION

3/70 강원대학교 Thread 스레드는 프로그램을 병렬로 실행할 수 있게 해준다 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이 터 ( 객체, 상수 ) 를 공유한다. 각각의 스레드는 자기만의 스택 ( 지역변수 ) 을 가지고 있다

Citation preview

Page 1: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

1/70강원대학교

14 주

멀티쓰레딩Multithreading

Page 2: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

2/70

Process and Thread

강원대학교

http://www.javamex.com/tutorials/threads/how_threads_work.shtml

Page 3: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

3/70강원대학교

Thread

• 스레드는 프로그램을 병렬로 실행할 수 있게 해준다• 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리

데이터 ( 객체 , 상수 ) 를 공유한다 .  • 각각의 스레드는 자기만의 스택 ( 지역변수 ) 을 가지고

있다

Page 4: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

4/70강원대학교

날짜 시간 출력 코드

final int REPETITIONS = 10;String greeting = "Hello!";

for (int i = 1; i <= REPETITIONS; i++) { Date now = new Date(); System.out.println(now + " " + greeting); Thread.sleep(DELAY); }

Page 5: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

5/70강원대학교

단일 쓰레드 실행

지금까지 해 온 방식대로 코드를 main 메소드에 적어줌

main 메소드를 실행하는 쓰레드가 하나 존재하게 됨

public static void main(String[] agrs) {코드

}

Page 6: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

6/70강원대학교

단일 쓰레드 실행

Fri May 28 15:21:35 KST 2010 Hello!Fri May 28 15:21:36 KST 2010 Hello!Fri May 28 15:21:37 KST 2010 Hello!Fri May 28 15:21:38 KST 2010 Hello!Fri May 28 15:21:39 KST 2010 Hello!Fri May 28 15:21:40 KST 2010 Hello!Fri May 28 15:21:41 KST 2010 Hello!Fri May 28 15:21:42 KST 2010 Hello!Fri May 28 15:21:43 KST 2010 Hello!Fri May 28 15:21:44 KST 2010 Hello!

Page 7: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

7/70강원대학교

두 개 이상의 쓰레드 실행기본 쓰레드에서 실행되는 main 메소드에서 추가적인 쓰레드를 만들어 실행하도록 해 줌

public static void main(String[] agrs) {Thread t1 = new Thread(); // 표준라이브러리의 Thread 클래스 !Thread t2 = new Thread();t1.start();t2.start();

}

기본 쓰레드와 t1, t2 등 모두 세 개의 쓰레드가 존재하게 됨기본 쓰레드는 위 코드를 실행한 후 종료t1 과 t2 쓰레드는 Thread 클래스의 run 메소드를 실행함Thread 클래스의 run 메소드는 아무 일도 하지 않음

Page 8: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

8/70강원대학교

두 개 이상의 쓰레드 실행t1, t2 쓰레드가 의미 있는 일을 하게 하려면 Thread 의 run 메소드를 재정의함

public class MyThread extends Thread {public void run() {

의미 있는 일을 하는 코드}

}

public static void main(String[] agrs) {Thread t1 = new MyThread();Thread t2 = new MyThread();t1.start();t2.start();

}

Page 9: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

9/70강원대학교

두 개 이상의 쓰레드 실행t1, t2 쓰레드가 의미 있는 일을 하게 하려면 Thread 의 run 메소드를 재정의함

public class MyThread extends Thread {public void run() {

일 초에 한 번씩 현재 시각을 출력하는 문장}

}

public static void main(String[] agrs) {Thread t1 = new MyThread();Thread t2 = new MyThread();t1.start();t2.start();

}

기본 쓰레드

t1t2

종료

Page 10: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

10/70강원대학교

두 쓰레드 실행

Fri May 28 15:24:09 KST 2010 Hello!Fri May 28 15:24:09 KST 2010 Hello!Fri May 28 15:24:10 KST 2010 Hello!Fri May 28 15:24:10 KST 2010 Hello!Fri May 28 15:24:11 KST 2010 Hello!Fri May 28 15:24:11 KST 2010 Hello!Fri May 28 15:24:12 KST 2010 Hello!Fri May 28 15:24:12 KST 2010 Hello!Fri May 28 15:24:13 KST 2010 Hello!Fri May 28 15:24:13 KST 2010 Hello!Fri May 28 15:24:14 KST 2010 Hello!Fri May 28 15:24:14 KST 2010 Hello!

Page 11: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

11/70강원대학교

두 개 이상의 쓰레드가 서로 다른 일을 할 수 도 있다 .public class Thread1 extends Thread {

public void run() {일 초에 한 번씩 현재 시각을 출력하는 문장

}}public class Thread2 extends Thread {

public void run() {음악을 연주하는 문장

}}public static void main(String[] agrs) {

Thread t1 = new Thread1();Thread t2 = new Thread2();t1.start();t2.start();

}

기본 쓰레드

t1t2

종료

Page 12: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

12/70강원대학교

쓰레드를 실행하는 다른 방법1. Runnable 인터페이스를 구현하는 클래스를 정의하고

수행할 작업을 run 메소드에 적어준다 .

// 표준 라이브러리에 정의되어 있는 인터페이스public interface Runnable{ void run();}

public class MyRunnable implements Runnable { public void run() { // 할 일 } }

Page 13: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

13/70강원대학교

Running a Thread3. 정의된 클래스 객체를 구성한다 .

4. Runnable 객체를 인자로 삼아 Thread 객체를 구성한다 .

5. Thread 에 start 메소들를 호출한다 .

Runnable r = new MyRunnable();

Thread t = new Thread(r);

t.start();

Page 14: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

14/70강원대학교

GreetingRunnable 뼈대

public class GreetingRunnable implements Runnable{ public GreetingRunnable(String aGreeting) { greeting = aGreeting; }

public void run() {

for (int i = 1; i <= 10; i++) {System.out.println(greeting);Thread.sleep(1000);

}

private String greeting; }

Page 15: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

15/70강원대학교

sleep

• 쓰레드를 잠시 중단시키기 위해서는 Thread 클래스의 sleep 메소드 호출

• 이 메소드는 InterruptedException 을 던지는 수가 있음 – 확인예외이므로 예외처리 필수

Thread.sleep(milliseconds)

Page 16: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

16/70강원대학교

Generic run Method

public void run() { try { Task statements } catch (InterruptedException exception) {

예외 처리 }}

Page 17: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

17/70강원대학교

File GreetingRunnable.java01: import java.util.Date;02: 03: /**04: A runnable that repeatedly prints a greeting.05: */06: public class GreetingRunnable implements Runnable07: {08: /**09: Constructs the runnable object.10: @param aGreeting the greeting to display11: */12: public GreetingRunnable(String aGreeting)13: {14: greeting = aGreeting;15: }16: 17: public void run()18: {

Page 18: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

18/70강원대학교

File GreetingRunnable.java19: try20: {21: for (int i = 1; i <= REPETITIONS; i++)22: {23: Date now = new Date();24: System.out.println(now + " " + greeting);25: Thread.sleep(DELAY); 26: }27: }28: catch (InterruptedException exception)29: {30: }31: }32: 33: private String greeting;34: 35: private static final int REPETITIONS = 10;36: private static final int DELAY = 1000;37: }

Page 19: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

19/70강원대학교

File GreetingThreadTester.java01: import java.util.Date;02: 03: /**04: This program tests the greeting thread by running two05: threads in parallel.06: */07: public class GreetingThreadTester08: {09: public static void main(String[] args)10: {11: GreetingRunnable r1 = new GreetingRunnable("Hello, World!");12: GreetingRunnable r2 = new GreetingRunnable("Goodbye, World!");

Page 20: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

20/70강원대학교

File GreetingThreadTester.java13: Thread t1 = new Thread(r1);14: Thread t2 = new Thread(r2);15: t1.start();16: t2.start();17: }18: }19:

Page 21: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

21/70강원대학교

OutputThu Dec 28 23:12:03 PST 2004 Hello, World! Thu Dec 28 23:12:03 PST 2004 Goodbye, World! Thu Dec 28 23:12:04 PST 2004 Hello, World! Thu Dec 28 23:12:05 PST 2004 Hello, World! Thu Dec 28 23:12:04 PST 2004 Goodbye, World! Thu Dec 28 23:12:05 PST 2004 Goodbye, World! Thu Dec 28 23:12:06 PST 2004 Hello, World! Thu Dec 28 23:12:06 PST 2004 Goodbye, World! Thu Dec 28 23:12:07 PST 2004 Hello, World! Thu Dec 28 23:12:07 PST 2004 Goodbye, World! Thu Dec 28 23:12:08 PST 2004 Hello, World! Thu Dec 28 23:12:08 PST 2004 Goodbye, World! Thu Dec 28 23:12:09 PST 2004 Hello, World! Thu Dec 28 23:12:09 PST 2004 Goodbye, World! Thu Dec 28 23:12:10 PST 2004 Hello, World! Thu Dec 28 23:12:10 PST 2004 Goodbye, World! Thu Dec 28 23:12:11 PST 2004 Goodbye, World! Thu Dec 28 23:12:11 PST 2004 Hello, World! Thu Dec 28 23:12:12 PST 2004 Goodbye, World! Thu Dec 28 23:12:12 PST 2004 Hello, World!

Page 22: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

22/70강원대학교

2 Runnables 2 Threads vs 1 Runnable and 2 Threads

GreetingRunnable r1 = new GreetingRunnable("Hello, World!");

GreetingRunnable r2 = new GreetingRunnable("Goodbye, World!");

Thread t1 = new Thread(r1);Thread t2 = new Thread(r2);t1.start();t2.start();

Thread t1 = new Thread(r1);Thread t2 = new Thread(r1);t1.start();t2.start();

Page 23: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

23/70강원대학교

Thread Scheduler• Thread scheduler 는 각 쓰레드를 짧은 시간

(time slice) 동안 실행 (activate) 시킨다 . • 쓰레드 실행 시간에는 작은 변이가 있을 수 있다

( 특히 입출력 동작시 ).• 쓰레드 실행 순서에는 어떤 보장도 없다 .

Page 24: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

24/70강원대학교

쓰레드에 인터럽트 걸기

• t.interrupt();

• InterruptedException 이 발생됨

Page 25: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

25/70강원대학교

public void run() { try { Task statements ( 가령 , 음악을 반복해서 연주 ) } catch (InterruptedException exception) {

인터럽트 처리 ( 가령 , 음악 연주를 끝내고 인사말 출력 ) }}

public class GreetingRunnable implements Runnable

GreetingRunnable r = new GreetingRunnable("Hello, World!");Thread t = new Thread(r);t.start();t.interrupt();

main

Page 26: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

26/70강원대학교

Thread

• 같은 코드를 실행하는 여러 스레드들은 각각 자기만의 지역변수를 갖는다 .

Page 27: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

27/70

두 개의 Runnable 두 개의 스레드public class NumberPrinter implements

Runnable{private static final int REPETITIONS = 100;private static final int DELAY = 1000;

private int number;public NumberPrinter(int n){ number = n; }

public void run() { try{ for (int i = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread()

String name = t.getName(); System.out.println(name + ": " + ++number); Thread.sleep(DELAY);

} }catch (InterruptedException exception) {}

}}

강원대학교

public class NumberThreadRunner{ public static void main(String[] args) {

NumberPrinter r1 = new Num-berPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); NumberPrinter r2 = new Num-berPrinter(0); Thread t2 = new Thread(r2); t2.setName("t2"); t1.start(); t2.start(); }}

t1: 1t2: 1t2: 2t1: 2t2: 3t1: 3t2: 4t1: 4t1: 5t2: 5t1: 6t2: 6

Page 28: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

28/70

한 개의 runnable 두 개의 스레드public class NumberPrinter implements

Runnable{private static final int REPETITIONS = 100;private static final int DELAY = 1000;

private int number;public NumberPrinter(int n){ number = n; }

public void run() { try{ for (int i = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread()

String name = t.getName(); System.out.println(name + ": " + ++number); Thread.sleep(DELAY);

} }catch (InterruptedException exception) {}

}}

강원대학교

public class NumberThreadRunner{ public static void main(String[] args) {

NumberPrinter r1 = new Num-berPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); Thread t2 = new Thread(r1); t2.setName("t2"); t1.start(); t2.start(); }}

t1: 38t2: 39t1: 40t2: 41t1: 42t2: 43t1: 44t2: 45t1: 46t2: 46t1: 47t2: 47t1: 48t2: 49t1: 50

Page 29: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

29/70

한 개의 runnable 두 개의 스레드public class NumberPrinter implements

Runnable{private static final int REPETITIONS = 100;private static final int DELAY = 1000;

private int number;public NumberPrinter(int n){ number = n; }

public void run() { try{ for (int i = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread()

String name = t.getName(); System.out.println(name + ": " + i); Thread.sleep(DELAY);

} }catch (InterruptedException exception) {}

}} 강원대학교

public class NumberThreadRunner{ public static void main(String[] args) {

NumberPrinter r1 = new Num-berPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); Thread t2 = new Thread(r1); t2.setName("t2"); t1.start(); t2.start(); }}

t1: 1t2: 1t2: 2t1: 2t2: 3t1: 3t1: 4t2: 4t2: 5t1: 5t2: 6t1: 6t2: 7t1: 7

Page 30: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

30/70

경쟁 조건 (Race Conditions)

강원대학교

Page 31: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

31/70강원대학교

경쟁 조건 (Race Conditions)• 여러 쓰레드가 하나의 자료를 공유하며 자료를

업데이트 할 때 이 자료가 엉망이 될 수 있다 .• 예 : 여러 쓰레드가 은행계좌를 조작할 때

Page 32: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

32/70

경쟁 조건 (Race Conditions)

강원대학교

balanceDeposit Thread

Withdraw Thread

deposit withdrawBankAccount

Page 33: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

33/70

BankAccount account = new BankAccount();DepositRunnable d = new DepositRunnable(account, AMOUNT, REPE-TITIONS);WithdrawRunnable w = new WithdrawRunnable(account, AMOUNT, REPETITIONS); Thread t1 = new Thread(d);Thread t2 = new Thread(w);t1.start();t2.start();

강원대학교

class WithdrawRunnable implements Runnable {

public void run() { try { for (int i = 1; i <= count; i+

+) {

account.withdraw(amount); Thread.sleep(DELAY); } } catch (InterruptedException exception) { }}

}

class DepositRunnable implements Runnable {

public void run() { try { for (int i = 1; i <= count;

i++) {

account.deposit(amount); Thread.sleep(DELAY); } } catch (InterruptedExcep-

tion exception) { }}

}

Page 34: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

34/70강원대학교

BankAccountpublic void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

public void withdraw(double amount) { System.out.print(“Withdrawing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

Page 35: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

35/70강원대학교

Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Withdrawing 100.0, new balance is -100.0Depositing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Withdrawing 100.0Depositing 100.0, new balance is -100.0, new balance is 100.0Depositing 100.0, new balance is 200.0Withdrawing 100.0, new balance is 100.0Depositing 100.0Withdrawing 100.0, new balance is 0.0, new balance is 200.0Depositing 100.0Withdrawing 100.0, new balance is 300.0, new balance is 100.0Depositing 100.0, new balance is 200.0Withdrawing 100.0, new balance is 100.0

Page 36: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

36/70강원대학교

Page 37: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

37/70강원대학교

이렇게 한다 해도 해결되지 않음

• Race condition can still occur:

public void deposit(double amount) { balance = balance + amount; System.out.print("Depositing " + amount + ", new balance is " + balance); }

balance = the right-hand-side value

Page 38: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

38/70강원대학교

File BankAccountThreadTester.-java

01: /**02: This program runs two threads that deposit and withdraw03: money from the same bank account. 04: */05: public class BankAccountThreadTester06: {07: public static void main(String[] args)08: {09: BankAccount account = new BankAccount();10: final double AMOUNT = 100;11: final int REPETITIONS = 1000;12: 13: DepositRunnable d = new DepositRunnable(14: account, AMOUNT, REPETITIONS);15: WithdrawRunnable w = new WithdrawRunnable(16: account, AMOUNT, REPETITIONS);

Page 39: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

39/70강원대학교

File BankAccountThreadTester.-java

17: 18: Thread t1 = new Thread(d);19: Thread t2 = new Thread(w);20: 21: t1.start();22: t2.start();23: }24: }25:

Page 40: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

40/70강원대학교

File DepositRunnable.java01: /**02: A deposit runnable makes periodic deposits to a bank // account.03: */04: public class DepositRunnable implements Runnable05: {06: /**07: Constructs a deposit runnable.08: @param anAccount the account into which to deposit // money09: @param anAmount the amount to deposit in each //repetition10: @param aCount the number of repetitions11: */12: public DepositRunnable(BankAccount anAccount, double anAmount,13: int aCount)14: {

Page 41: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

41/70강원대학교

File DepositRunnable.java15: account = anAccount;16: amount = anAmount;17: count = aCount;18: }19: 20: public void run()21: {22: try23: {24: for (int i = 1; i <= count; i++)25: {26: account.deposit(amount);27: Thread.sleep(DELAY);28: }29: }30: catch (InterruptedException exception) {}31: }32:

Page 42: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

42/70강원대학교

File DepositRunnable.java33: private static final int DELAY = 1; 34: private BankAccount account;35: private double amount;36: private int count;37: }

Page 43: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

43/70강원대학교

File WithdrawalRunnable.java01: /**02: A withdraw runnable makes periodic withdrawals from a // bank account.03: */04: public class WithdrawRunnable implements Runnable05: {06: /**07: Constructs a withdraw runnable.08: @param anAccount the account from which to withdraw money09: @param anAmount the amount to deposit in each repetition10: @param aCount the number of repetitions11: */12: public WithdrawRunnable(BankAccount anAccount, double anAmount,13: int aCount)14: {15: account = anAccount;16: amount = anAmount;17: count = aCount;18: }

Page 44: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

44/70강원대학교

File WithdrawalRunnable.java19: 20: public void run()21: {22: try23: {24: for (int i = 1; i <= count; i++)25: {26: account.withdraw(amount);27: Thread.sleep(DELAY);28: }29: }30: catch (InterruptedException exception) {}31: }32: 33: private static final int DELAY = 1; 34: private BankAccount account;35: private double amount;36: private int count;37: }

Page 45: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

45/70강원대학교

File BankAccount.java01: /**02: A bank account has a balance that can be changed by 03: deposits and withdrawals.04: */05: public class BankAccount06: {07: /**08: Constructs a bank account with a zero balance.09: */10: public BankAccount()11: {12: balance = 0;13: }14: 15: /**16: Deposits money into the bank account.17: @param amount the amount to deposit18: */

Page 46: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

46/70강원대학교

File BankAccount.java19: public void deposit(double amount)20: {21: System.out.print("Depositing " + amount);22: double newBalance = balance + amount;23: System.out.println(", new balance is " + newBalance);24: balance = newBalance;25: }26: 27: /**28: Withdraws money from the bank account.29: @param amount the amount to withdraw30: */31: public void withdraw(double amount)32: {33: System.out.print("Withdrawing " + amount);34: double newBalance = balance - amount;35: System.out.println(", new balance is " + newBalance);36: balance = newBalance;37: }

Page 47: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

47/70강원대학교

File BankAccount.java38: 39: /**40: Gets the current balance of the bank account.41: @return the current balance42: */43: public double getBalance()44: {45: return balance;46: }47: 48: private double balance;49: }

Page 48: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

48/70강원대학교

File BankAccount.javaOutputDepositing 100.0, new balance is 100.0 Withdrawing 100.0, new balance is 0.0 Depositing 100.0, new balance is 100.0 Withdrawing 100.0, new balance is 0.0 . . . Withdrawing 100.0, new balance is 400.0 Depositing 100.0, new balance is 500.0 Withdrawing 100.0, new balance is 400.0 Withdrawing 100.0, new balance is 300.0

Page 49: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

49/70강원대학교

객체 접근 동기화(Synchronizing Object Access)

• 두 개 이상이 쓰레드가 하나의 객체에 접근할 때 그 시간을 통제하여 경쟁조건을 해결하는 것

• 어떻게 통제 ?– 한 쓰레드가 단위 작업을 끝내야 쓰레드 스위칭이

일어나도록 함① Synchronized method② Lock

Page 50: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

50/70강원대학교

public synchronized void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

public synchronized void withdraw(double amount) { System.out.print(“Withdrawing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

하나의 BankAccount 객체에 대한 synchronized 메소드 호출들은 서로 섞이지 않는다 .

① Synchronized Method

Page 51: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

51/70

Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0Depositing 100.0, new balance is 100.0Withdrawing 100.0, new balance is 0.0

강원대학교

Page 52: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

52/70

① Synchronized Method• 하나의 BankAccount 객체에 대한 synchronized method (deposit,

withdraw) 호출은 서로 섞이지 않는다 .• 한 synchronized 메소드가 시작되면 끝날 때까지 다른 synchronized

메소드가 시작되지 않는다 .

강원대학교

double balance

synchronized meth-ods (deposit, with-

draw)

Deposit Thread

Withdraw Thread

deposit withdraw

BankAccount

Page 53: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

53/70강원대학교

② Lock• 공유되는 객체에 대응하는 lock 객체를 이용함 .

public class BankAccount { public BankAccount() { balanceLock = new ReentrantLock(); . . . } . . . private Lock balanceLock;}

Page 54: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

54/70강원대학교

• 공유 자료를 조작하는 코드를 lock 과 unlock으로 둘러쌈

balanceLock.lock(); Code that manipulates the shared resource balanceLock.unlock();

② Lock

Page 55: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

55/70강원대학교

• 쓰레드가 lock 호출에 성공하면 unlock 을 호출할 때까지 lock 을 점유함

• 다른 쓰레드가 lock 을 점유하고 있는 동안 lock을 호출하는 쓰레드는 일시적으로 비활성화됨(deactivated)

• Thread scheduler 는 주기적으로 쓰레드를 활성화시켜 다시 lock 을 점유할 기회를 줌

② Lock

Page 56: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

56/70강원대학교

• lock 과 unlock 사이에서 예외가 발생하면 unlock 이 영영 실행되지 못함

• 이런 문제를 해결하기 위해 unlock 을 finally 절에 넣음

② Lock

Page 57: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

57/70강원대학교

public void deposit(double amount) { balanceLock.lock(); try { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } finally { balanceLock.unlock(); } }

* withraw 메소드도 같은 요령으로 처리

② Lock

Page 58: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

58/70강원대학교

Deadlock( 교착상태 )• 쓰레드들이 서로 다른 쓰레드의 작업이 마무리

되기를 기다리고 있으나 실제로는 서로 맞물려 더이상 진행하지 못하는 상태

Page 59: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

59/70강원대학교

Deadlock( 교착상태 ) 예

public void withdraw(double amount) { balanceChangeLock.lock(); try { while (balance < amount) Wait for the balance to grow . . . } finally { balanceChangeLock.unlock(); }}

• 예금 인출 시 잔고가 모자라면 입금될 때까지 기다리게 하는 경우

이 부분에서 sleep을 호출하면 lock 을 계속 점유하므로 다른 쓰레드가 deposit할 수 없게 됨 – deadlock!

Page 60: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

60/70강원대학교

Deadlock( 교착상태 ) 을 방지하는 법

• Condition 객체 사용 • 각 Condition 객체는 특정 Lock 객체에 속함 • 쓰레드가 점유하고 있는 Lock 에 속하는 Condition 에게

await 를 사용하면 쓰레드가 일시적으로 Lock 을 놓게 됨 .• 다른 쓰레드가 그 Condition 에게 signalAll 메소드를

호출하면 await 중인 모든 쓰레드가 await 로부터 복귀함 .

Page 61: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

61/70강원대학교

Condition Objectspublic class BankAccount { public BankAccount() { balanceLock = new ReentrantLock();

condition = balanceLock.newCondition(); . . . } . . . private Lock balanceLock; private Condition condition; }

Page 62: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

62/70강원대학교

Condition Objectspublic void withdraw(double amount) { balanceLock.lock(); try { while (balance < amount) condition.await(); . . . } finally { balanceLock.unlock(); } }

Page 63: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

63/70강원대학교

Condition Objects

public void deposit(double amount) {balanceLock.lock();try {

System.out.print("Depositing " + amount);double newBalance = balance + amount;System.out.println(", new balance is " + newBalance);balance = newBalance;condition.signalAll();

}finally {

balanceLock.unlock();}

}

Page 64: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

64/70강원대학교

Condition Objects• 쓰레드가 Condition 에 await 를 호출하면

– 쓰레드가 block 상태로 가면서 일시적으로 Lock 을 놓음으로써 다른 쓰레드가 Lock 을 점유할 기회를 줌

– Block 상태로 간 쓰레드는 다른 쓰레드가 그 condition 에 signalAll 을 호출하거나 inter-rupt 를 걸어 주면 깨어남 .

Page 65: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

65/70강원대학교

BankAccountThreadTester.java01: /**02: This program runs four threads that deposit and withdraw03: money from the same bank account. 04: */05: public class BankAccountThreadTester06: {07: public static void main(String[] args)08: {09: BankAccount account = new BankAccount();10: final double AMOUNT = 100;11: final int REPETITIONS = 1000;12: 13: DepositRunnable d1 = new DepositRunnable(14: account, AMOUNT, REPETITIONS);15: WithdrawRunnable w1 = new WithdrawRunnable(16: account, AMOUNT, REPETITIONS);17: DepositRunnable d2 = new DepositRunnable(18: account, AMOUNT, REPETITIONS);

Page 66: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

66/70강원대학교

BankAccountThreadTester.java

19: WithdrawRunnable w2 = new WithdrawRunnable(account, 20: AMOUNT, REPETITIONS);21: 22: Thread t1 = new Thread(d1);23: Thread t2 = new Thread(w1);24: Thread t3 = new Thread(d2);25: Thread t4 = new Thread(w2);26: 27: t1.start();28: t2.start();29: t3.start();30: t4.start();31: }32: }33:

Page 67: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

67/70강원대학교

File BankAccount.java

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;

public class BankAccount{ private double balance = 0.0; private Lock balanceLock = new ReentrantLock(); private Condition condition = balanceLock.newCondition();

Page 68: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

68/70강원대학교

public void deposit(double amount) {balanceLock.lock();try {

System.out.print("Depositing " + amount);double newBalance = balance + amount;System.out.println(", new balance is " + newBalance);balance = newBalance;condition.signalAll();

}finally {

balanceLock.unlock();}

}

Page 69: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

69/70강원대학교

public void withdraw(double amount) {balanceLock.lock();try {

while (balance < amount) {try {

condition.await();}catch(InterruptedException e) { }

}System.out.print("Withdrawing " + amount);double newBalance = balance - amount;System.out.println(", new balance is " + newBalance);balance = newBalance;

}finally {

balanceLock.unlock();}

}

Page 70: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

70/70강원대학교

/** Gets the current balance of the bank account. @return the current balance */ public double getBalance() { return balance; } }

Page 71: 1/70 강원대학교 14 주 멀티쓰레딩 Multithreading. 2/70 Process and Thread 강원대학교

71/70강원대학교

Output

Depositing 100.0, new balance is 100.0 Withdrawing 100.0, new balance is 0.0 Depositing 100.0, new balance is 100.0 Depositing 100.0, new balance is 200.0 . . . Withdrawing 100.0, new balance is 100.0 Depositing 100.0, new balance is 200.0 Withdrawing 100.0, new balance is 100.0 Withdrawing 100.0, new balance is 0.0