62
객객객객객객객객객 객객객객객 객객객객객객객객객 13 객객 – 객객객객객 1

객체지향프로그래밍 13 주차 – 멀티쓰레딩

  • Upload
    rhett

  • View
    97

  • Download
    4

Embed Size (px)

DESCRIPTION

객체지향프로그래밍 13 주차 – 멀티쓰레딩. 제 13 주 멀티쓰레딩 (Multithreading). 제 13 주 강의 목표 여러 쓰레드가 어떻게 병렬도 실행되는 지 이해함 쓰레드를 구현하는 법을 배움 레이스 컨디션과 데드락에 대해 배움 락과 컨디션을 사용함으로써 공유자료가 엉망이 되지 않도록 하는 법을 배움 애니메이션에 스레드를 이용하는 법을 배움. Thread. 스레드 는 프로그램을 병렬로 실행할 수 있게 해준다 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터를 공유한다 . - PowerPoint PPT Presentation

Citation preview

Page 1: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

객체지향프로그래밍

13 주차 – 멀티쓰레딩

1

Page 2: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

제 13 주

멀티쓰레딩(Multithreading)

제 13 주 강의 목표•여러 쓰레드가 어떻게 병렬도 실행되는 지 이해함•쓰레드를 구현하는 법을 배움•레이스 컨디션과 데드락에 대해 배움•락과 컨디션을 사용함으로써 공유자료가 엉망이 되지 않도록

하는 법을 배움•애니메이션에 스레드를 이용하는 법을 배움

2

Page 3: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Thread

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

데이터를 공유한다 . • 각각의 스레드는 자기만의 스택과 레지스터를 가지고

있다

3

Page 4: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

날짜 시간 출력 코드

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); }

4

Page 5: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

단일 쓰레드 실행

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!

5

Page 6: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

두 쓰레드 실행

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!

6

Page 7: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Running a Thread1. Runnable 인터페이스를 구현하는 클래스를 정의하고

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

public interface Runnable{ void run();}

public class MyRunnable implements Runnable { public void run() { // Task statements go here } }

7

Page 8: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

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

Runnable r = new MyRunnable();

Thread t = new Thread(r);

t.start();

8

Page 9: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

GreetingRunnable 뼈대

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

public void run() { // Task statements go here . . . } // Fields used by the task statements private String greeting; }

9

Page 10: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

GreetingRunnable 의 run 메소드에서 할 일

• Print a time stamp • Print the greeting • Wait a second

• 현재 날짜와 시간은 Date 객체를 구성함으로써 얻을 수 있다 .

Date now = new Date();

10

Page 11: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

GreetingRunnable 의 run 메소드에서 할 일

• 1 초 기다리기 위해서는 Thread 클래스의 sleep 메소드 호출

• A sleeping thread can generate an InterruptedException – Catch the exception – Terminate the thread

Thread.sleep(milliseconds)

11

Page 12: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Generic run Method

public void run() { try { Task statements } catch (InterruptedException exception) { } Clean up, if necessary }

12

Page 13: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: {

13

Page 14: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: }

14

Page 15: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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!");

15

Page 16: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

16

Page 17: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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!

17

Page 18: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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();

18

Page 19: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

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

19

Page 20: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Terminating Threads• 쓰레드는 run 메소드가 완료되면 종료된다 . • run 메소드가 완료되기 전에 쓰레드를 종료시키려면 그

쓰레드에 interrupt 를 호출한다 .

• interrupt 가 쓰레드를 강제로 종료시키는 것은 아니다 . 쓰레드 자료구조 내의 특정 비트를 세트할 뿐이다 . 쓰레드가 이를 감지하고 스스로 종료해야 한다 .

t.interrupt();

20

Page 21: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Terminating Threadspublic void run() { for (int i = 1; i <= REPETITIONS && !Thread.interrupted(); i++) { Do work } Clean up }

인터럽트가 걸렸는지 스스로 확인하는 법

21

Page 22: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Terminating Threads• sleep 메소드 실행 중 interrupt 가 걸리면

InterruptedException 이 발생됨

• Interrupt 가 걸린 상태에서 sleep 메소드가 호출되는 경우에도 InterruptedException 이 발생됨

• run 메소드 내에 sleep 문장이 있는 경우에는 interrupt 가 걸렸는지 일일이 확인할 필요 없이 InterruptedException 발생 여부만을 감시하면 됨

22

Page 23: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Terminating Threadspublic void run() { try { for (int i = 1; i <= REPETITIONS; i++) { Do work and sleep } } catch (InterruptedException exception) { 아무것도 하지 않거나 ( 종료 ) 적절한 작업을 함

} Clean up }

23

Page 24: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

public class MyRunnable implements Runnable { public void run() { try { System.out.println(1); Thread.sleep(1000); System.out.println(2); } catch (InterruptedException exception) { System.out.println(3); } System.out.println(4); }}

Thread t = new Thread(new MyRunnable()); t.start(); t.interrupt();

24

Page 25: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

25

Page 26: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

DepositRunnable 의 run 메소드

WithdrawRunnable class is similar

public void run() { try { for (int i = 1; i <= count; i++) { account.deposit(amount); Thread.sleep(DELAY); } } catch (InterruptedException exception) { }}

26

Page 27: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Sample Application• BankAccount 객체 구성 • 두 개의 쓰레드를 구성

– t1 은 $100 를 10 번 저축함– t2 는 $100 를 10 번 인출함

27

Page 28: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

* withraw 메소드도 유사한 형태로 구현

28

Page 29: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Sample Application

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 . . . Withdrawing 100.0, new balance is 0.0

Depositing 100.0Withdrawing 100.0, new balance is 100.0, new balance is -100.0

29

Page 30: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교 30

Page 31: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

• 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

31

Page 32: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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);

32

Page 33: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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:

33

Page 34: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: {

34

Page 35: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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:

35

Page 36: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

36

Page 37: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: }

37

Page 38: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: }

38

Page 39: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: */

39

Page 40: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: }

40

Page 41: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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: }

41

Page 42: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

42

Page 43: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

• Lock 인터페이스와 Lock 인터페이스를 구현한 클래스를 이용– ReentrantLock: 흔히 쓰이는 lock 클래스 – Lock 은 Java version 5.0 이후 기능

43

Page 44: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Synchronizing Object Access• 통상 공유자료에 접근하는 메소드를 갖는

클래스에 lock 객체 삽입

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

44

Page 45: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Synchronizing Object Access

• 공유 자료에 접근하는 코드를 lock 과 unlock으로 둘러쌈

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

45

Page 46: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Synchronizing Object Access

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

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

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

46

Page 47: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Synchronizing Object Access

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

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

47

Page 48: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

48

Page 49: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

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

49

Page 50: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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!

50

Page 51: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

• Condition 객체 사용 • Condition 객체를 사용하면 쓰레드가

일시적으로 lock 을 놓았다가 나중에 다시 점유하게 됨

• 각 Condition 객체는 특정 lock 객체에 속함

51

Page 52: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Condition Objectspublic class BankAccount { public BankAccount() { balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); . . . } . . . private Lock balanceChangeLock; private Condition sufficientFundsCondition; }

52

Page 53: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

53

Page 54: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

– 쓰레드가 block 상태로 감– Block 상태로 간 쓰레드는 unblock 될 때까지

thread scheduler 에 의해 activate 되지 않음 (time slice 를 배정받지 못함 )

– 다른 쓰레드가 lock 객체를 점유할 기회를 줌

54

Page 55: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

Condition Objects• block 된 쓰레드를 unblock 하려면 다른

쓰레드가 그 condition 에 signalAll 메소드를 호출해 주어야 함

• signalAll 은 그 condition 으로 block 된 모든 쓰레드를 unblock 해 줌

sufficientFundsCondition.signalAll();

55

Page 56: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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);

56

Page 57: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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:

57

Page 58: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

File BankAccount.javaimport java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;

/** A bank account has a balance that can be changed by deposits and withdrawals.*/public class BankAccount{ /** Constructs a bank account with a zero balance. */ public BankAccount() { balance = 0; balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); }

58

Page 59: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

/** Deposits money into the bank account. @param amount the amount to deposit */ public void deposit(double amount) { balanceChangeLock.lock(); try { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; sufficientFundsCondition.signalAll(); } finally { balanceChangeLock.unlock(); } }

59

Page 60: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

/** Withdraws money from the bank account. @param amount the amount to withdraw */ public void withdraw(double amount) throws InterruptedException { balanceChangeLock.lock(); try { while (balance < amount) sufficientFundsCondition.await(); System.out.print("Withdrawing " + amount); double newBalance = balance - amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } finally { balanceChangeLock.unlock(); } }

60

Page 61: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

61

Page 62: 객체지향프로그래밍 13 주차  – 멀티쓰레딩

객체지향프로그래밍 강원대학교

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

62