12 주 멀티쓰레딩 네트워크 프로그래밍

93
1/93 자자자자자자자 자자자자자 12 자 자자자자자 자자자자 자자자자자

Upload: jason

Post on 19-Jan-2016

55 views

Category:

Documents


0 download

DESCRIPTION

12 주 멀티쓰레딩 네트워크 프로그래밍. 멀티쓰레딩 (Multithreading). Thread. 스레드 는 프로그램을 병렬로 실행할 수 있게 해준다 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터를 공유한다 . 각각의 스레드는 자기만의 스택과 레지스터를 가지고 있다. 날짜 시간 출력 코드. final int REPETITIONS = 10; String greeting = "Hello!"; for (int i = 1; i

TRANSCRIPT

Page 1: 12 주 멀티쓰레딩 네트워크 프로그래밍

1/93자바프로그래밍 강원대학교

12 주

멀티쓰레딩네트워크 프로그래밍

Page 2: 12 주 멀티쓰레딩 네트워크 프로그래밍

2/93자바프로그래밍 강원대학교

멀티쓰레딩(Multithreading)

Page 3: 12 주 멀티쓰레딩 네트워크 프로그래밍

3/93자바프로그래밍 강원대학교

Thread

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

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

있다

Page 4: 12 주 멀티쓰레딩 네트워크 프로그래밍

4/93자바프로그래밍 강원대학교

날짜 시간 출력 코드

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: 12 주 멀티쓰레딩 네트워크 프로그래밍

5/93자바프로그래밍 강원대학교

단일 쓰레드 실행

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 6: 12 주 멀티쓰레딩 네트워크 프로그래밍

6/93자바프로그래밍 강원대학교

두 쓰레드 실행

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 7: 12 주 멀티쓰레딩 네트워크 프로그래밍

7/93자바프로그래밍 강원대학교

Running a Thread

1. Runnable 인터페이스를 구현하는 클래스를 정의하고 수행할 작업을 run 메소드에 적어준다 .

public interface Runnable{ void run();}

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

Page 8: 12 주 멀티쓰레딩 네트워크 프로그래밍

8/93자바프로그래밍 강원대학교

Running a Thread

3. 정의된 클래스 객체를 구성한다 .

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

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

Runnable r = new MyRunnable();

Thread t = new Thread(r);

t.start();

Page 9: 12 주 멀티쓰레딩 네트워크 프로그래밍

9/93자바프로그래밍 강원대학교

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

Page 10: 12 주 멀티쓰레딩 네트워크 프로그래밍

10/93자바프로그래밍 강원대학교

GreetingRunnable 의 run 메소드에서 할 일

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

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

Date now = new Date();

Page 11: 12 주 멀티쓰레딩 네트워크 프로그래밍

11/93자바프로그래밍 강원대학교

GreetingRunnable 의 run 메소드에서 할 일

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

• A sleeping thread can generate an Inter-ruptedException – Catch the exception – Terminate the thread

Thread.sleep(milliseconds)

Page 12: 12 주 멀티쓰레딩 네트워크 프로그래밍

12/93자바프로그래밍 강원대학교

Generic run Method

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

Page 13: 12 주 멀티쓰레딩 네트워크 프로그래밍

13/93자바프로그래밍 강원대학교

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 14: 12 주 멀티쓰레딩 네트워크 프로그래밍

14/93자바프로그래밍 강원대학교

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 15: 12 주 멀티쓰레딩 네트워크 프로그래밍

15/93자바프로그래밍 강원대학교

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 16: 12 주 멀티쓰레딩 네트워크 프로그래밍

16/93자바프로그래밍 강원대학교

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

Page 17: 12 주 멀티쓰레딩 네트워크 프로그래밍

17/93자바프로그래밍 강원대학교

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 18: 12 주 멀티쓰레딩 네트워크 프로그래밍

18/93자바프로그래밍 강원대학교

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 19: 12 주 멀티쓰레딩 네트워크 프로그래밍

19/93자바프로그래밍 강원대학교

Thread Scheduler

• Thread scheduler 는 각 쓰레드를 짧은 시간 (time slice) 동안 실행 (activate) 시킨다 .

• 쓰레드 실행 시간에는 작은 변이가 있을 수 있다( 특히 입출력 동작시 ).

• 쓰레드 실행 순서에는 어떤 보장도 없다 .

Page 20: 12 주 멀티쓰레딩 네트워크 프로그래밍

20/93자바프로그래밍 강원대학교

Terminating Threads

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

쓰레드에 interrupt 를 호출한다 .

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

t.interrupt();

Page 21: 12 주 멀티쓰레딩 네트워크 프로그래밍

21/93자바프로그래밍 강원대학교

Terminating Threads

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

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

Page 22: 12 주 멀티쓰레딩 네트워크 프로그래밍

22/93자바프로그래밍 강원대학교

Terminating Threads

• sleep 메소드 실행 중 interrupt 가 걸리면 Interrupt-edException 이 발생됨

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

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

Page 23: 12 주 멀티쓰레딩 네트워크 프로그래밍

23/93자바프로그래밍 강원대학교

Terminating Threads

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

Page 24: 12 주 멀티쓰레딩 네트워크 프로그래밍

24/93자바프로그래밍 강원대학교

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

Page 25: 12 주 멀티쓰레딩 네트워크 프로그래밍

25/93

Thread 를 실행하는 두번째 방법public class MyThread extends Thread {

public run(){...

}}

Thread t = new MyThread();t.start();

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

Page 26: 12 주 멀티쓰레딩 네트워크 프로그래밍

26/93

첫번째 방법 !

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

public class MyRunnable extends Runnable {public run(){

...

}}

Runnable r = new MyRunnable();Thread t = new Thread(r);t.start();

Page 27: 12 주 멀티쓰레딩 네트워크 프로그래밍

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

Thread

• 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터 ( 객체의 필드 ) 를 공유한다 .  

• 각각의 스레드는 자기만의 스택 ( 지역변수 ) 을 가지고 있다

Page 28: 12 주 멀티쓰레딩 네트워크 프로그래밍

28/93

두 개의 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 29: 12 주 멀티쓰레딩 네트워크 프로그래밍

29/93

한 개의 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 30: 12 주 멀티쓰레딩 네트워크 프로그래밍

30/93

한 개의 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 31: 12 주 멀티쓰레딩 네트워크 프로그래밍

31/93

Networking

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

Page 32: 12 주 멀티쓰레딩 네트워크 프로그래밍

32/93

네트워크 기초

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

Page 33: 12 주 멀티쓰레딩 네트워크 프로그래밍

33/93

Host Address

IP addresse 203.252.11.24

domain name dmrl.kangwon.ac.kr

Domain Naming Service (DNS)

• domain name IP address

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

Page 34: 12 주 멀티쓰레딩 네트워크 프로그래밍

34/93

Port Number

• 한 호스트 ( 하드웨어 ) 에 여러 서버 ( 소프트웨어 프로세스 ) 가 있음

• 각 서버마다 포트가 할당됨• 포트 - 데이타 송수신에 사용되는 네트워크 출입구

• 클라이언트가 서버와 통신하기 위해서는 서버의 ip주소와 포트번호를 알아야 함

• 클라이언트가 보내는 매 패킷마다 서버의 ip 주소와 포트번호가 들어 있음

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

Page 35: 12 주 멀티쓰레딩 네트워크 프로그래밍

35/93

자바의 소켓 (Socket)

– 포트 (port) 를 프로그램 안에서 제어할 수 있게 함

– 자바에서는 TCP, UDP 통신을 위한 각각 별도의 소켓 제공• TCP 의 경우에는 서버 소켓 , 클라이언트 소켓이 따로 존재• UDP 의 경우에는 하나의 소켓만 존재

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

Page 36: 12 주 멀티쓰레딩 네트워크 프로그래밍

36/93

소켓과 포트

클라이언트 서버

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

포트

소켓

서버소켓

서버 혹은 클라이언트

Page 37: 12 주 멀티쓰레딩 네트워크 프로그래밍

37/93

네트워킹의 종류

• TCP 네트워킹– 신뢰성이 있는 연결지향적 통신 프로토콜

• 데이타가 전송 도중 소실될 경우 재전송할 수 있다 .• 전송 순서대로 데이타가 도착된다 .

• UDP 네트워킹– 신뢰성이 없는 비 연결지향적 통신 프로토콜

• 데이타가 전송 도중 소실될 수 있다 .• 전송 순서대로 데이타가 도착되지 않을 수도 있다 .• 신뢰성이 없는 대신 전송 속도는 TCP 보다 빠르다 .

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

Page 38: 12 주 멀티쓰레딩 네트워크 프로그래밍

38/93

Header Contents of TCP/UDP Pack-ets• Internet address of the recipient

• Port number of the recipient

• Protocol (TCP or UDP)

• Internet address of the sender

• Port number of the sender

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

Page 39: 12 주 멀티쓰레딩 네트워크 프로그래밍

39/93

TCP 프로그래밍

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

Page 40: 12 주 멀티쓰레딩 네트워크 프로그래밍

40/93

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.

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

Page 41: 12 주 멀티쓰레딩 네트워크 프로그래밍

41/93

A Simple Echo Serverimport 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()));

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

Page 42: 12 주 멀티쓰레딩 네트워크 프로그래밍

42/93

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

}

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

Page 43: 12 주 멀티쓰레딩 네트워크 프로그래밍

43/93

Test the EchoServer with Telnet

Use telnet as a client.

c:\Users\java> telnet localhost 8008Hello!Enter BYE to exit.Hi, this is from venusEcho: Hi, this is from venusBYEEcho: BYE호스트에 대한 연결을 잃었습니다 .

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

Page 44: 12 주 멀티쓰레딩 네트워크 프로그래밍

44/93

A Simple Clientimport 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.getOutput-

Stream()));

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

Page 45: 12 주 멀티쓰레딩 네트워크 프로그래밍

45/93

// send data to the serverfor (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 serverwhile (true) {

String str = in.readLine();if (str == null) break;else System.out.println(str);

}

} catch (Exception e) {}}

}

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

Page 46: 12 주 멀티쓰레딩 네트워크 프로그래밍

46/93

Eclipse 에서 서버를 종료시키는 방법

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

①②

① 콘솔 창 리스트를 보이게 하여② 서버가 돌고 있는 콘솔을 선택하고③ 서버를 종료시킴

Page 47: 12 주 멀티쓰레딩 네트워크 프로그래밍

47/93

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

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

Page 48: 12 주 멀티쓰레딩 네트워크 프로그래밍

48/93

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

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

Page 49: 12 주 멀티쓰레딩 네트워크 프로그래밍

49/93

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

}

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

Page 50: 12 주 멀티쓰레딩 네트워크 프로그래밍

50/93

Multi-threaded 서버 작동 절차

클라이언트 서버

서버 대기

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

ServerSocket s = new ServerSocket(8008);Socket socket = s.accept();

Page 51: 12 주 멀티쓰레딩 네트워크 프로그래밍

51/93

클라이언트 서버

클라이언트 접속 요청

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

Socket socket = new Socket(host, 8008);

Page 52: 12 주 멀티쓰레딩 네트워크 프로그래밍

52/93

클라이언트 서버

서버 쓰레드 시작

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

new ClientHandler(socket).start();

Page 53: 12 주 멀티쓰레딩 네트워크 프로그래밍

53/93

클라이언트 서버

클라이언트 접속 요청

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

Socket socket = new Socket(host, 8008);

Page 54: 12 주 멀티쓰레딩 네트워크 프로그래밍

54/93

클라이언트 서버

서버 쓰레드 시작

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

포트

소켓

서버소켓

서버 혹은 클라이언트

new ClientHandler(socket).start();

Page 55: 12 주 멀티쓰레딩 네트워크 프로그래밍

55/93

참고자료

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

Page 56: 12 주 멀티쓰레딩 네트워크 프로그래밍

56/93자바프로그래밍 강원대학교

경쟁 조건 (Race Conditions)

• 여러 쓰레드가 하나의 자료를 공유하며 자료를 업데이트 할 때 이 자료가 엉망이 될 수 있다 .

• 예 : 여러 쓰레드가 은행계좌를 조작할 때

Page 57: 12 주 멀티쓰레딩 네트워크 프로그래밍

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

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

Page 58: 12 주 멀티쓰레딩 네트워크 프로그래밍

58/93자바프로그래밍 강원대학교

Sample Application

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

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

Page 59: 12 주 멀티쓰레딩 네트워크 프로그래밍

59/93자바프로그래밍 강원대학교

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 메소드도 유사한 형태로 구현

Page 60: 12 주 멀티쓰레딩 네트워크 프로그래밍

60/93자바프로그래밍 강원대학교

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

Page 61: 12 주 멀티쓰레딩 네트워크 프로그래밍

61/93자바프로그래밍 강원대학교

Page 62: 12 주 멀티쓰레딩 네트워크 프로그래밍

62/93자바프로그래밍 강원대학교

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

• 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 63: 12 주 멀티쓰레딩 네트워크 프로그래밍

63/93자바프로그래밍 강원대학교

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 64: 12 주 멀티쓰레딩 네트워크 프로그래밍

64/93자바프로그래밍 강원대학교

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 65: 12 주 멀티쓰레딩 네트워크 프로그래밍

65/93자바프로그래밍 강원대학교

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 66: 12 주 멀티쓰레딩 네트워크 프로그래밍

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

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 67: 12 주 멀티쓰레딩 네트워크 프로그래밍

67/93자바프로그래밍 강원대학교

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

Page 68: 12 주 멀티쓰레딩 네트워크 프로그래밍

68/93자바프로그래밍 강원대학교

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 69: 12 주 멀티쓰레딩 네트워크 프로그래밍

69/93자바프로그래밍 강원대학교

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 70: 12 주 멀티쓰레딩 네트워크 프로그래밍

70/93자바프로그래밍 강원대학교

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 71: 12 주 멀티쓰레딩 네트워크 프로그래밍

71/93자바프로그래밍 강원대학교

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 72: 12 주 멀티쓰레딩 네트워크 프로그래밍

72/93자바프로그래밍 강원대학교

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 73: 12 주 멀티쓰레딩 네트워크 프로그래밍

73/93자바프로그래밍 강원대학교

File BankAccount.java

OutputDepositing 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 74: 12 주 멀티쓰레딩 네트워크 프로그래밍

74/93자바프로그래밍 강원대학교

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

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

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

Page 75: 12 주 멀티쓰레딩 네트워크 프로그래밍

75/93자바프로그래밍 강원대학교

Synchronizing Object Access

• 통상 공유자료에 접근하는 메소드를 갖는 클래스에 lock 객체 삽입

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

Page 76: 12 주 멀티쓰레딩 네트워크 프로그래밍

76/93자바프로그래밍 강원대학교

Synchronizing Object Access

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

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

Page 77: 12 주 멀티쓰레딩 네트워크 프로그래밍

77/93자바프로그래밍 강원대학교

Synchronizing Object Access

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

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

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

Page 78: 12 주 멀티쓰레딩 네트워크 프로그래밍

78/93자바프로그래밍 강원대학교

Synchronizing Object Access

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

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

Page 79: 12 주 멀티쓰레딩 네트워크 프로그래밍

79/93자바프로그래밍 강원대학교

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 메소드도 같은 요령으로 처리

Page 80: 12 주 멀티쓰레딩 네트워크 프로그래밍

80/93자바프로그래밍 강원대학교

Deadlock( 교착상태 )

• 쓰레드들이 서로 다른 쓰레드의 작업이 마무리 되기를 기다리고 있으나 실제로는 서로 맞물려 더이상 진행하지 못하는 상태

Page 81: 12 주 멀티쓰레딩 네트워크 프로그래밍

81/93자바프로그래밍 강원대학교

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 82: 12 주 멀티쓰레딩 네트워크 프로그래밍

82/93자바프로그래밍 강원대학교

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

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

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

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

Page 83: 12 주 멀티쓰레딩 네트워크 프로그래밍

83/93자바프로그래밍 강원대학교

Condition Objects

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

Page 84: 12 주 멀티쓰레딩 네트워크 프로그래밍

84/93자바프로그래밍 강원대학교

Condition Objects

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

Page 85: 12 주 멀티쓰레딩 네트워크 프로그래밍

85/93자바프로그래밍 강원대학교

Condition Objects

• 쓰레드가 await 를 호출하면 – 쓰레드가 block 상태로 감– Block 상태로 간 쓰레드는 unblock 될 때까지

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

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

Page 86: 12 주 멀티쓰레딩 네트워크 프로그래밍

86/93자바프로그래밍 강원대학교

Condition Objects

• block 된 쓰레드를 unblock 하려면 다른 쓰레드가 그 condition 에 signalAll 메소드를 호출해 주어야 함

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

sufficientFundsCondition.signalAll();

Page 87: 12 주 멀티쓰레딩 네트워크 프로그래밍

87/93자바프로그래밍 강원대학교

BankAccountThreadTester.java

01: /**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 88: 12 주 멀티쓰레딩 네트워크 프로그래밍

88/93자바프로그래밍 강원대학교

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 89: 12 주 멀티쓰레딩 네트워크 프로그래밍

89/93자바프로그래밍 강원대학교

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

Page 90: 12 주 멀티쓰레딩 네트워크 프로그래밍

90/93자바프로그래밍 강원대학교

/** 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(); } }

Page 91: 12 주 멀티쓰레딩 네트워크 프로그래밍

91/93자바프로그래밍 강원대학교

/** 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(); } }

Page 92: 12 주 멀티쓰레딩 네트워크 프로그래밍

92/93자바프로그래밍 강원대학교

/** 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;}

Page 93: 12 주 멀티쓰레딩 네트워크 프로그래밍

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

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