Presentation is loading. Please wait.

Presentation is loading. Please wait.

자바프로그래밍강원대학교 12 주 멀티쓰레딩 네트워크 프로그래밍 1. 자바프로그래밍강원대학교 멀티쓰레딩 (Multithreading) 2.

Similar presentations


Presentation on theme: "자바프로그래밍강원대학교 12 주 멀티쓰레딩 네트워크 프로그래밍 1. 자바프로그래밍강원대학교 멀티쓰레딩 (Multithreading) 2."— Presentation transcript:

1 자바프로그래밍강원대학교 12 주 멀티쓰레딩 네트워크 프로그래밍 1

2 자바프로그래밍강원대학교 멀티쓰레딩 (Multithreading) 2

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

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

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

6 자바프로그래밍강원대학교 두 쓰레드 실행 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! 6

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

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

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

10 자바프로그래밍강원대학교 GreetingRunnable 의 run 메소드에서 할 일 Print a time stamp Print the greeting Wait a second 현재 날짜와 시간은 Date 객체를 구성함으로써 얻 을 수 있다. Date now = new Date(); 10

11 자바프로그래밍강원대학교 GreetingRunnable 의 run 메소드에서 할 일 1 초 기다리기 위해서는 Thread 클래스의 sleep 메 소드 호출 A sleeping thread can generate an InterruptedException –Catch the exception –Terminate the thread Thread.sleep(milliseconds) 11

12 자바프로그래밍강원대학교 Generic run Method public void run() { try { Task statements } catch (InterruptedException exception) { } Clean up, if necessary } 12

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

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

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

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

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

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

19 자바프로그래밍강원대학교 Thread Scheduler Thread scheduler 는 각 쓰레드를 짧은 시간 (time slice) 동안 실행 (activate) 시킨다. 쓰레드 실행 시간에는 작은 변이가 있을 수 있다 ( 특히 입출력 동작시 ). 쓰레드 실행 순서에는 어떤 보장도 없다. 19

20 자바프로그래밍강원대학교 Terminating Threads 쓰레드는 run 메소드가 완료되면 종료된다. run 메소드가 완료되기 전에 쓰레드를 종료시키려면 그 쓰레 드에 interrupt 를 호출한다. interrupt 가 쓰레드를 강제로 종료시키는 것은 아니다. 쓰레드 자료구조 내의 특정 비트를 세트할 뿐이다. 쓰레드가 이를 감지하고 스스로 종료해야 한다. t.interrupt(); 20

21 자바프로그래밍강원대학교 Terminating Threads public void run() { for (int i = 1; i <= REPETITIONS && !Thread.interrupted(); i++) { Do work } Clean up } 인터럽트가 걸렸는지 스스로 확인하는 법 21

22 자바프로그래밍강원대학교 Terminating Threads sleep 메소드 실행 중 interrupt 가 걸리면 InterruptedException 이 발생됨 Interrupt 가 걸린 상태에서 sleep 메소드가 호출되는 경우 에도 InterruptedException 이 발생됨 run 메소드 내에 sleep 문장이 있는 경우에는 interrupt 가 걸 렸는지 일일이 확인할 필요 없이 InterruptedException 발 생 여부만을 감시하면 됨 22

23 자바프로그래밍강원대학교 Terminating Threads public void run() { try { for (int i = 1; i <= REPETITIONS; i++) { Do work and sleep } } catch (InterruptedException exception) { 아무것도 하지 않거나 ( 종료 ) 적절한 작업을 함 } Clean up } 23

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

25 Thread 를 실행하는 두번째 방법 public class MyThread extends Thread { public run(){... } Thread t = new MyThread(); t.start(); 자바프로그래밍강원대학교 25

26 첫번째 방법 ! 자바프로그래밍강원대학교 26 public class MyRunnable extends Runnable { public run(){... } Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

27 Networking 자바프로그래밍강원대학교 27

28 네트워크 기초 자바프로그래밍강원대학교 28

29 Host Address IP addresse 203.252.11.24 domain name dmrl.kangwon.ac.kr Domain Naming Service (DNS) domain name  IP address 자바프로그래밍강원대학교 29

30 Port Number 한 호스트 ( 하드웨어 ) 에 여러 서버 ( 소프트웨어 프로세스 ) 가 있음 각 서버마다 포트가 할당됨 포트 - 데이타 송수신에 사용되는 네트워크 출입구 클라이언트가 서버와 통신하기 위해서는 서버의 ip 주소 와 포트번호를 알아야 함 클라이언트가 보내는 매 패킷마다 서버의 ip 주소와 포트 번호가 들어 있음 자바프로그래밍강원대학교 30

31 자바의 소켓 (Socket) – 포트 (port) 를 프로그램 안에서 제어할 수 있게 함 – 자바에서는 TCP, UDP 통신을 위한 각각 별도의 소켓 제공 TCP 의 경우에는 서버 소켓, 클라이언트 소켓이 따로 존재 UDP 의 경우에는 하나의 소켓만 존재 자바프로그래밍강원대학교 31

32 소켓과 포트 클라이언트 서버 자바프로그래밍강원대학교 32 포트 소켓 서버소켓 서버 혹은 클라이언트

33 네트워킹의 종류 TCP 네트워킹 – 신뢰성이 있는 연결지향적 통신 프로토콜 데이타가 전송 도중 소실될 경우 재전송할 수 있다. 전송 순서대로 데이타가 도착된다. UDP 네트워킹 – 신뢰성이 없는 비 연결지향적 통신 프로토콜 데이타가 전송 도중 소실될 수 있다. 전송 순서대로 데이타가 도착되지 않을 수도 있다. 신뢰성이 없는 대신 전송 속도는 TCP 보다 빠르다. 자바프로그래밍강원대학교 33

34 Header Contents of TCP/UDP Packets Internet address of the recipient Port number of the recipient Protocol (TCP or UDP) Internet address of the sender Port number of the sender 자바프로그래밍강원대학교 34

35 TCP 프로그래밍 자바프로그래밍강원대학교 35

36 Java Networking -- Socket Server socket class: ServerSocket –wait for requests from clients. –after a request is received, a client socket is generated. Client socket class: Socket –an endpoint for communication between two apps/applets. –obtained by contacting a server generated by the server socket Communication is handled by input/output streams. –Socket provides an input and an output stream. 자바프로그래밍강원대학교 36

37 A Simple Echo Server import java.io.*; import java.net.*; public class EchoServer { public static void main(String[] args) { try { ServerSocket s = new ServerSocket(8008); while (true) { Socket socket = s.accept(); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter( socket.getOutputStream())); 자바프로그래밍강원대학교 37

38 out.println("Hello!...."); out.println("Enter BYE to exit."); out.flush(); while (true) { String str = in.readLine(); if (str == null) { break; // client closed connection } else { out.println("Echo: " + str); out.flush(); if (str.trim().equals("BYE")) break; } socket.close(); } } catch (Exception e) {} } 자바프로그래밍강원대학교 38

39 Test the EchoServer with Telnet Use telnet as a client. c:\Users\java> telnet localhost 8008 Hello! Enter BYE to exit. Hi, this is from venus Echo: Hi, this is from venus BYE Echo: BYE 호스트에 대한 연결을 잃었습니다. 자바프로그래밍강원대학교 39

40 A Simple Client import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) { try { String host; if (args.length > 0) host = args[0]; else host = "localhost"; Socket socket = new Socket(host, 8008); BufferedReader in= new BufferedReader( new InputStreamReader( socket.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter( socket.getOutputStream())); 자바프로그래밍강원대학교 40

41 // send data to the server for (int i = 1; i <= 10; i++) { System.out.println("Sending: line " + i); out.println("line " + i); out.flush(); } out.println("BYE"); out.flush(); //receive data from the server while (true) { String str = in.readLine(); if (str == null) break; else System.out.println(str); } } catch (Exception e) {} } 자바프로그래밍강원대학교 41

42 Eclipse 에서 서버를 종료시키는 방법 자바프로그래밍강원대학교 42 ① ② ③ ① 콘솔 창 리스트를 보이게 하여 ② 서버가 돌고 있는 콘솔을 선택하고 ③ 서버를 종료시킴

43 Multi-Threaded Echo Server To handle multiple requests simultaneously. In the main() method, spawn a thread for each request. import java.net.ServerSocket; import java.net.Socket; public class MultiEchoServer { public static void main(String[] args) { try { ServerSocket s = new ServerSocket(8009); while (true) { Socket socket = s.accept(); new ClientHandler(socket).start(); } } catch (Exception e) {} } 자바프로그래밍강원대학교 43

44 Client Handler public class ClientHandler extends Thread { protected Socket socket; public ClientHandler(Socket socket) { this.socket = socket; } public void run() { try { BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter( socket.getOutputStream())); 자바프로그래밍강원대학교 44

45 out.println("Hello!..."); out.println("Enter BYE to exit."); out.flush(); while (true) { String str = in.readLine(); if (str == null) { break; } else { out.println("Echo: " + str); out.flush(); if (str.trim().equals("BYE")) break; } socket.close(); } catch (Exception e) {} } 자바프로그래밍강원대학교 45

46 Multi-threaded 서버 작 동 절차 클라이언트 서버 서버 대기 자바프로그래밍강원대학교 46 ServerSocket s = new ServerSocket(8008); Socket socket = s.accept();

47 클라이언트 서버 클라이언트 접속 요청 자바프로그래밍강원대학교 47 Socket socket = new Socket(host, 8008);

48 클라이언트 서버 서버 쓰레드 시작 자바프로그래밍강원대학교 48 new ClientHandler(socket).start();

49 클라이언트 서버 클라이언트 접속 요청 자바프로그래밍강원대학교 49 Socket socket = new Socket(host, 8008);

50 클라이언트 서버 서버 쓰레드 시작 자바프로그래밍강원대학교 50 포트 소켓 서버소켓 서버 혹은 클라이언트 new ClientHandler(socket).start();

51 참고자료 자바프로그래밍강원대학교 51

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

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

54 자바프로그래밍강원대학교 Sample Application BankAccount 객체 구성 두 개의 쓰레드를 구성 –t1 은 $100 를 10 번 저축함 –t2 는 $100 를 10 번 인출함 54

55 자바프로그래밍강원대학교 Sample Application public void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } * withraw 메소드도 유사한 형태로 구현 55

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

57 자바프로그래밍강원대학교 57

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

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

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

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

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

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

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

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

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

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

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

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

70 자바프로그래밍강원대학교 객체 접근 동기화 (Synchronizing Object Access) 두 개 이상이 쓰레드가 하나의 객체에 접근할 때 그 시간을 통제하여 경쟁조건을 해결하는 것 Lock 인터페이스와 Lock 인터페이스를 구현한 클 래스를 이용 –ReentrantLock : 흔히 쓰이는 lock 클래스 –Lock 은 Java version 5.0 이후 기능 70

71 자바프로그래밍강원대학교 Synchronizing Object Access 통상 공유자료에 접근하는 메소드를 갖는 클래스 에 lock 객체 삽입 public class BankAccount { public BankAccount() { balanceChangeLock = new ReentrantLock();... }... private Lock balanceChangeLock; } 71

72 자바프로그래밍강원대학교 Synchronizing Object Access 공유 자료에 접근하는 코드를 lock 과 unlock 으 로 둘러쌈 balanceChangeLock.lock(); Code that manipulates the shared resource balanceChangeLock.unlock(); 72

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

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

75 자바프로그래밍강원대학교 Synchronizing Object Access 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; } finally { balanceChangeLock.unlock(); } } * withraw 메소드도 같은 요령으로 처리 75

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

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

78 자바프로그래밍강원대학교 Deadlock( 교착상태 ) 을 방지하는 법 Condition 객체 사용 Condition 객체를 사용하면 쓰레드가 일시적으로 lock 을 놓았다가 나중에 다시 점유하게 됨 각 Condition 객체는 특정 lock 객체에 속함 78

79 자바프로그래밍강원대학교 Condition Objects public class BankAccount { public BankAccount() { balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition();... }... private Lock balanceChangeLock; private Condition sufficientFundsCondition; } 79

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

81 자바프로그래밍강원대학교 Condition Objects 쓰레드가 await 를 호출하면 – 쓰레드가 block 상태로 감 –Block 상태로 간 쓰레드는 unblock 될 때까지 thread scheduler 에 의해 activate 되지 않음 (time slice 를 배정받지 못함 ) – 다른 쓰레드가 lock 객체를 점유할 기회를 줌 81

82 자바프로그래밍강원대학교 Condition Objects block 된 쓰레드를 unblock 하려면 다른 쓰레드 가 그 condition 에 signalAll 메소드를 호 출해 주어야 함 signalAll 은 그 condition 으로 block 된 모든 쓰 레드를 unblock 해 줌 sufficientFundsCondition.signalAll(); 82

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

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

85 자바프로그래밍강원대학교 File BankAccount.java import 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(); } 85

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

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

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

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


Download ppt "자바프로그래밍강원대학교 12 주 멀티쓰레딩 네트워크 프로그래밍 1. 자바프로그래밍강원대학교 멀티쓰레딩 (Multithreading) 2."

Similar presentations


Ads by Google