Presentation is loading. Please wait.

Presentation is loading. Please wait.

1/66 자바프로그래밍강원대학교 14 주 멀티쓰레딩 Multithreading. 2/66 Process and Thread 자바프로그래밍강원대학교

Similar presentations


Presentation on theme: "1/66 자바프로그래밍강원대학교 14 주 멀티쓰레딩 Multithreading. 2/66 Process and Thread 자바프로그래밍강원대학교"— Presentation transcript:

1 1/66 자바프로그래밍강원대학교 14 주 멀티쓰레딩 Multithreading

2 2/66 Process and Thread 자바프로그래밍강원대학교 http://www.javamex.com/tutorials/threads/how_threads_work.shtml

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

4 4/66 자바프로그래밍강원대학교 날짜 시간 출력 코드 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); }

5 5/66 자바프로그래밍강원대학교 단일 쓰레드 실행 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!

6 6/66 자바프로그래밍강원대학교 두 쓰레드 실행 Fri May 28 15:24:09 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:12 KST 2010 Hello! Fri May 28 15:24:13 KST 2010 Hello! Fri May 28 15:24:14 KST 2010 Hello!

7 7/66 자바프로그래밍강원대학교 쓰레드를 실행하는 방법 1.Runnable 인터페이스를 구현하는 클래스를 정의하 고 수행할 작업을 run 메소드에 적어준다. public interface Runnable { void run(); } public class MyRunnable implements Runnable { public void run() { // Task statements go here } }

8 8/66 자바프로그래밍강원대학교 Running a Thread 3. 정의된 클래스 객체를 구성한다. 4.Runnable 객체를 인자로 삼아 Thread 객체를 구성한 다. 5.Thread 에 start 메소들를 호출한다. Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

9 9/66 자바프로그래밍강원대학교 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; }

10 10/66 자바프로그래밍강원대학교 sleep 쓰레드를 잠시 중단시키기 위해서는 Thread 클래스의 sleep 메소드 호출 이 메소드는 InterruptedException 을 던지는 수가 있음 – 확인예외이므로 예외처리 필수 Thread.sleep(milliseconds)

11 11/66 자바프로그래밍강원대학교 Generic run Method public void run() { try { Task statements } catch (InterruptedException exception) { 예외 처리 } }

12 12/66 자바프로그래밍강원대학교 File GreetingRunnable.java 01: import java.util.Date; 02: 03: /** 04: A runnable that repeatedly prints a greeting. 05: */ 06: public class GreetingRunnable implements Runnable 07: { 08: /** 09: Constructs the runnable object. 10: @param aGreeting the greeting to display 11: */ 12: public GreetingRunnable(String aGreeting) 13: { 14: greeting = aGreeting; 15: } 16: 17: public void run() 18: {

13 13/66 자바프로그래밍강원대학교 File GreetingRunnable.java 19: try 20: { 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 14/66 자바프로그래밍강원대학교 File GreetingThreadTester.java 01: import java.util.Date; 02: 03: /** 04: This program tests the greeting thread by running two 05: threads in parallel. 06: */ 07: public class GreetingThreadTester 08: { 09: public static void main(String[] args) 10: { 11: GreetingRunnable r1 = new GreetingRunnable("Hello, World!"); 12: GreetingRunnable r2 = new GreetingRunnable("Goodbye, World!");

15 15/66 자바프로그래밍강원대학교 File GreetingThreadTester.java 13: Thread t1 = new Thread(r1); 14: Thread t2 = new Thread(r2); 15: t1.start(); 16: t2.start(); 17: } 18: } 19:

16 16/66 자바프로그래밍강원대학교 Output Thu 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 17/66 자바프로그래밍강원대학교 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 18/66 자바프로그래밍강원대학교 Thread Scheduler Thread scheduler 는 각 쓰레드를 짧은 시간 (time slice) 동안 실행 (activate) 시킨다. 쓰레드 실행 시간에는 작은 변이가 있을 수 있다 ( 특히 입출력 동작시 ). 쓰레드 실행 순서에는 어떤 보장도 없다.

19 19/66 자바프로그래밍강원대학교 쓰레드에 인터럽트 걸기 t.interrupt(); InterruptedException 이 발생됨

20 20/66 자바프로그래밍강원대학교 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

21 21/66 Thread 를 실행하는 다른 방법 public class MyThread extends Thread { public void run(){... } Thread t = new MyThread(); t.start(); 자바프로그래밍강원대학교 첫번째 방법 public class MyRunnable implements Runnable { public void run(){... } Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

22 22/66 자바프로그래밍강원대학교 Thread 같은 코드를 실행하는 여러 스레드들은 각각 자기만의 지 역변수를 갖는다.

23 23/66 두 개의 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 NumberPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); NumberPrinter r2 = new NumberPrinter(0); Thread t2 = new Thread(r2); t2.setName("t2"); t1.start(); t2.start(); } t1: 1 t2: 1 t2: 2 t1: 2 t2: 3 t1: 3 t2: 4 t1: 4 t1: 5 t2: 5 t1: 6 t2: 6

24 24/66 한 개의 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 NumberPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); Thread t2 = new Thread(r1); t2.setName("t2"); t1.start(); t2.start(); } t1: 38 t2: 39 t1: 40 t2: 41 t1: 42 t2: 43 t1: 44 t2: 45 t1: 46 t2: 46 t1: 47 t2: 47 t1: 48 t2: 49 t1: 50

25 25/66 한 개의 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 NumberPrinter(0); Thread t1 = new Thread(r1); t1.setName("t1"); Thread t2 = new Thread(r1); t2.setName("t2"); t1.start(); t2.start(); } t1: 1 t2: 1 t2: 2 t1: 2 t2: 3 t1: 3 t1: 4 t2: 4 t2: 5 t1: 5 t2: 6 t1: 6 t2: 7 t1: 7

26 26/66 경쟁 조건 (Race Conditions) 자바프로그래밍강원대학교

27 27/66 자바프로그래밍강원대학교 경쟁 조건 (Race Conditions) 여러 쓰레드가 하나의 자료를 공유하며 자료를 업 데이트 할 때 이 자료가 엉망이 될 수 있다. 예 : 여러 쓰레드가 은행계좌를 조작할 때

28 28/66 경쟁 조건 (Race Conditions) 자바프로그래밍강원대학교 balance Deposit Thread Withdraw Thread depositwithdraw BankAccount

29 29/66 BankAccount account = new BankAccount(); DepositRunnable d = new DepositRunnable(account, AMOUNT, REPETITIONS); 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 (InterruptedException exception) { } }

30 30/66 자바프로그래밍강원대학교 BankAccount public 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; }

31 31/66 자바프로그래밍강원대학교 Depositing 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 -100.0 Depositing 100.0, new balance is 0.0 Depositing 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.0Depositing 100.0, new balance is -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.0Withdrawing 100.0, new balance is 0.0, new balance is 200.0 Depositing 100.0Withdrawing 100.0, new balance is 300.0, new balance is 100.0 Depositing 100.0, new balance is 200.0 Withdrawing 100.0, new balance is 100.0

32 32/66 자바프로그래밍강원대학교

33 33/66 자바프로그래밍강원대학교 이렇게 한다 해도 해결되지 않음 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

34 34/66 자바프로그래밍강원대학교 File BankAccountThreadTester.java 01: /** 02: This program runs two threads that deposit and withdraw 03: money from the same bank account. 04: */ 05: public class BankAccountThreadTester 06: { 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);

35 35/66 자바프로그래밍강원대학교 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:

36 36/66 자바프로그래밍강원대학교 File DepositRunnable.java 01: /** 02: A deposit runnable makes periodic deposits to a bank // account. 03: */ 04: public class DepositRunnable implements Runnable 05: { 06: /** 07: Constructs a deposit runnable. 08: @param anAccount the account into which to deposit // money 09: @param anAmount the amount to deposit in each //repetition 10: @param aCount the number of repetitions 11: */ 12: public DepositRunnable(BankAccount anAccount, double anAmount, 13: int aCount) 14: {

37 37/66 자바프로그래밍강원대학교 File DepositRunnable.java 15: account = anAccount; 16: amount = anAmount; 17: count = aCount; 18: } 19: 20: public void run() 21: { 22: try 23: { 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:

38 38/66 자바프로그래밍강원대학교 File DepositRunnable.java 33: private static final int DELAY = 1; 34: private BankAccount account; 35: private double amount; 36: private int count; 37: }

39 39/66 자바프로그래밍강원대학교 File WithdrawalRunnable.java 01: /** 02: A withdraw runnable makes periodic withdrawals from a // bank account. 03: */ 04: public class WithdrawRunnable implements Runnable 05: { 06: /** 07: Constructs a withdraw runnable. 08: @param anAccount the account from which to withdraw money 09: @param anAmount the amount to deposit in each repetition 10: @param aCount the number of repetitions 11: */ 12: public WithdrawRunnable(BankAccount anAccount, double anAmount, 13: int aCount) 14: { 15: account = anAccount; 16: amount = anAmount; 17: count = aCount; 18: }

40 40/66 자바프로그래밍강원대학교 File WithdrawalRunnable.java 19: 20: public void run() 21: { 22: try 23: { 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: }

41 41/66 자바프로그래밍강원대학교 File BankAccount.java 01: /** 02: A bank account has a balance that can be changed by 03: deposits and withdrawals. 04: */ 05: public class BankAccount 06: { 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 deposit 18: */

42 42/66 자바프로그래밍강원대학교 File BankAccount.java 19: 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 withdraw 30: */ 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: }

43 43/66 자바프로그래밍강원대학교 File BankAccount.java 38: 39: /** 40: Gets the current balance of the bank account. 41: @return the current balance 42: */ 43: public double getBalance() 44: { 45: return balance; 46: } 47: 48: private double balance; 49: }

44 44/66 자바프로그래밍강원대학교 File BankAccount.java 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 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

45 45/66 자바프로그래밍강원대학교 객체 접근 동기화 (Synchronizing Object Access) 두 개 이상이 쓰레드가 하나의 객체에 접근할 때 그 시간을 통제하여 경쟁조건을 해결하는 것 어떻게 통제 ? – 한 쓰레드가 단위 작업을 끝내야 쓰레드 스위칭이 일어 나도록 함 ① Synchronized method ② Lock

46 46/66 자바프로그래밍강원대학교 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

47 47/66 Depositing 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 Depositing 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 Depositing 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 Depositing 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 Depositing 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 자바프로그래밍강원대학교

48 48/66 ① Synchronized Method 하나의 BankAccount 객체에 대한 synchronized method (deposit, withdraw) 호출은 서로 섞이지 않는다. 한 synchronized 메소드가 시작되면 끝날 때까지 다른 synchronized 메소드 가 시작되지 않는다. 자바프로그래밍강원대학교 double balance synchronized methods (deposit, withdraw) Deposit Thread Withdraw Thread deposit withdraw BankAccount

49 49/66 자바프로그래밍강원대학교 ② Lock 공유되는 객체에 대응하는 lock 객체를 이용함. public class BankAccount { public BankAccount() { balanceLock = new ReentrantLock();... }... private Lock balanceLock; }

50 50/66 자바프로그래밍강원대학교 공유 자료를 조작하는 코드를 lock 과 unlock 으 로 둘러쌈 balanceLock.lock(); Code that manipulates the shared resource balanceLock.unlock(); ② Lock

51 51/66 자바프로그래밍강원대학교 쓰레드가 lock 호출에 성공하면 unlock 을 호 출할 때까지 lock 을 점유함 다른 쓰레드가 lock 을 점유하고 있는 동안 lock 을 호출하는 쓰레드는 일시적으로 비활성화됨 (deactivated) Thread scheduler 는 주기적으로 쓰레드를 활성화 시켜 다시 lock 을 점유할 기회를 줌 ② Lock

52 52/66 자바프로그래밍강원대학교 lock 과 unlock 사이에서 예외가 발생하면 unlock 이 영영 실행되지 못함 이런 문제를 해결하기 위해 unlock 을 finally 절에 넣음 ② Lock

53 53/66 자바프로그래밍강원대학교 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

54 54/66 자바프로그래밍강원대학교 Deadlock( 교착상태 ) 쓰레드들이 서로 다른 쓰레드의 작업이 마무리 되 기를 기다리고 있으나 실제로는 서로 맞물려 더이 상 진행하지 못하는 상태

55 55/66 자바프로그래밍강원대학교 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!

56 56/66 자바프로그래밍강원대학교 Deadlock( 교착상태 ) 을 방지하는 법 Condition 객체 사용 각 Condition 객체는 특정 Lock 객체에 속함 쓰레드가 점유하고 있는 Lock 에 속하는 Condition 에게 await 를 사용하면 쓰레드가 일시적으로 Lock 을 놓게 됨. 다른 쓰레드가 그 Condition 에게 notifyAll 메소드를 호출하 면 await 중인 모든 쓰레드가 await 로부터 복귀함.

57 57/66 자바프로그래밍강원대학교 Condition Objects public class BankAccount { public BankAccount() { balanceLock = new ReentrantLock(); condition = balanceLock.newCondition();... }... private Lock balanceLock; private Condition condition; }

58 58/66 자바프로그래밍강원대학교 Condition Objects public void withdraw(double amount) { balanceLock.lock(); try { while (balance < amount) condition.await();... } finally { balanceLock.unlock(); } }

59 59/66 자바프로그래밍강원대학교 Condition Objects 쓰레드가 Condition 에 await 를 호출하면 – 쓰레드가 block 상태로 가면서 일시적으로 Lock 을 놓음으로써 다른 쓰레드가 Lock 을 점유할 기 회를 줌 –Block 상태로 간 쓰레드는 다른 쓰레드가 그 condition 에 notifyAll 을 호출하거나 interrupt 를 걸어 주면 깨어남.

60 60/66 자바프로그래밍강원대학교 BankAccountThreadTester.java 01: /** 02: This program runs four threads that deposit and withdraw 03: money from the same bank account. 04: */ 05: public class BankAccountThreadTester 06: { 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);

61 61/66 자바프로그래밍강원대학교 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:

62 62/66 자바프로그래밍강원대학교 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();

63 63/66 자바프로그래밍강원대학교 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(); }

64 64/66 자바프로그래밍강원대학교 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(); }

65 65/66 자바프로그래밍강원대학교 /** Gets the current balance of the bank account. @return the current balance */ public double getBalance() { return balance; } }

66 66/66 자바프로그래밍강원대학교 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


Download ppt "1/66 자바프로그래밍강원대학교 14 주 멀티쓰레딩 Multithreading. 2/66 Process and Thread 자바프로그래밍강원대학교"

Similar presentations


Ads by Google