930 likes | 1.09k Views
12 주 멀티쓰레딩 네트워크 프로그래밍. 멀티쓰레딩 (Multithreading). Thread. 스레드 는 프로그램을 병렬로 실행할 수 있게 해준다 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터를 공유한다 . 각각의 스레드는 자기만의 스택과 레지스터를 가지고 있다. 날짜 시간 출력 코드. final int REPETITIONS = 10; String greeting = "Hello!"; for (int i = 1; i <= REPETITIONS; i++) {
E N D
12주멀티쓰레딩네트워크 프로그래밍 강원대학교
멀티쓰레딩(Multithreading) 강원대학교
Thread • 스레드는 프로그램을 병렬로 실행할 수 있게 해준다 • 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터를 공유한다. • 각각의 스레드는 자기만의 스택과 레지스터를 가지고 있다 강원대학교
날짜 시간 출력 코드 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); } 강원대학교
단일 쓰레드 실행 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! 강원대학교
두 쓰레드 실행 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! 강원대학교
Running a Thread • Runnable인터페이스를 구현하는 클래스를 정의하고 수행할 작업을 run메소드에 적어준다. public class MyRunnable implements Runnable { public void run() { // Task statements go here } } public interface Runnable{ void run();} 강원대학교
Running a Thread • 정의된 클래스 객체를 구성한다. • Runnable 객체를 인자로 삼아 Thread객체를 구성한다. • Thread에 start메소들를 호출한다. Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); 강원대학교
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; } 강원대학교
GreetingRunnable의 run 메소드에서 할 일 • Print a time stamp • Print the greeting • Wait a second • 현재 날짜와 시간은 Date 객체를 구성함으로써 얻을 수 있다. Date now = new Date(); 강원대학교
GreetingRunnable의 run 메소드에서 할 일 • 1초 기다리기 위해서는 Thread 클래스의 sleep 메소드 호출 • A sleeping thread can generate an InterruptedException • Catch the exception • Terminate the thread Thread.sleep(milliseconds) 강원대학교
Generic run Method public void run() { try {Task statements } catch (InterruptedException exception) { }Clean up, if necessary} 강원대학교
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: { 강원대학교
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: } 강원대학교
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!"); 강원대학교
File GreetingThreadTester.java 13: Thread t1 = new Thread(r1); 14: Thread t2 = new Thread(r2); 15: t1.start(); 16: t2.start(); 17: } 18: } 19: 강원대학교
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! 강원대학교
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(); 강원대학교
Thread Scheduler • Thread scheduler는 각 쓰레드를 짧은 시간 (time slice) 동안 실행(activate)시킨다. • 쓰레드 실행 시간에는 작은 변이가 있을 수 있다(특히 입출력 동작시). • 쓰레드 실행 순서에는 어떤 보장도 없다. 강원대학교
Terminating Threads • 쓰레드는 run메소드가 완료되면 종료된다. • run 메소드가 완료되기 전에 쓰레드를 종료시키려면 그 쓰레드에 interrupt를 호출한다. • interrupt가 쓰레드를 강제로 종료시키는 것은 아니다.쓰레드 자료구조 내의 특정 비트를 세트할 뿐이다. 쓰레드가 이를 감지하고 스스로 종료해야 한다. t.interrupt(); 강원대학교
Terminating Threads public void run() { for (int i = 1; i <= REPETITIONS && !Thread.interrupted(); i++) {Do work } Clean up} 인터럽트가 걸렸는지 스스로 확인하는 법 강원대학교
Terminating Threads • sleep 메소드 실행 중 interrupt가 걸리면 InterruptedException이 발생됨 • Interrupt가 걸린 상태에서 sleep 메소드가 호출되는 경우에도 InterruptedException이 발생됨 • run 메소드 내에 sleep 문장이 있는 경우에는 interrupt가 걸렸는지 일일이 확인할 필요 없이 InterruptedException 발생 여부만을 감시하면 됨 강원대학교
Terminating Threads public void run() { try { for (int i = 1; i <= REPETITIONS; i++) { Do work and sleep} } catch (InterruptedException exception) { 아무것도 하지 않거나 (종료) 적절한 작업을 함 } Clean up} 강원대학교
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(); 강원대학교
Thread를 실행하는 두번째 방법 강원대학교 public class MyThread extends Thread { public run(){ ... } } Thread t = new MyThread(); t.start();
첫번째 방법! public class MyRunnableextends Runnable { public run(){ ... } } Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); 강원대학교
Thread • 병렬로 실행되는 쓰레드들은 프로그램 코드와 메모리 데이터(객체의 필드)를 공유한다. • 각각의 스레드는 자기만의 스택(지역변수)을 가지고 있다 강원대학교
두 개의 runnable 두 개의 스레드 publicclassNumberThreadRunner{ publicstaticvoidmain(String[] args) { NumberPrinter r1 = newNumberPrinter(0); Thread t1 = newThread(r1); t1.setName("t1"); NumberPrinter r2 = newNumberPrinter(0); Thread t2 = newThread(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 강원대학교 publicclassNumberPrinterimplementsRunnable{ privatestaticfinalintREPETITIONS= 100; privatestaticfinalintDELAY= 1000; privateintnumber; publicNumberPrinter(intn){ number= n; } publicvoidrun(){ try{ for(inti = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread() String name = t.getName(); System.out.println(name + ": "+ ++number); Thread.sleep(DELAY); } } catch(InterruptedException exception) {} } }
한 개의 runnable 두 개의 스레드 publicclassNumberThreadRunner{ publicstaticvoidmain(String[] args) { NumberPrinter r1 = newNumberPrinter(0); Thread t1 = newThread(r1); t1.setName("t1"); Thread t2 = newThread(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 강원대학교 publicclassNumberPrinterimplementsRunnable{ privatestaticfinalintREPETITIONS= 100; privatestaticfinalintDELAY= 1000; privateintnumber; publicNumberPrinter(intn){ number= n; } publicvoidrun(){ try{ for(inti = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread() String name = t.getName(); System.out.println(name + ": "+ ++number); Thread.sleep(DELAY); } } catch(InterruptedException exception) {} } }
한 개의 runnable 두 개의 스레드 publicclassNumberThreadRunner{ publicstaticvoidmain(String[] args) { NumberPrinter r1 = newNumberPrinter(0); Thread t1 = newThread(r1); t1.setName("t1"); Thread t2 = newThread(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 강원대학교 publicclassNumberPrinterimplementsRunnable{ privatestaticfinalintREPETITIONS= 100; privatestaticfinalintDELAY= 1000; privateintnumber; publicNumberPrinter(intn){ number= n; } publicvoidrun(){ try{ for(inti = 1; i <= REPETITIONS; i++){ Thread t = Thread.currentThread() String name = t.getName(); System.out.println(name + ": "+ i); Thread.sleep(DELAY); } } catch(InterruptedException exception) {} } }
Networking 강원대학교
네트워크 기초 강원대학교
Host Address • IP addresse 203.252.11.24 • domain name dmrl.kangwon.ac.kr • Domain Naming Service (DNS) • domain name IP address 강원대학교
Port Number • 한 호스트(하드웨어)에 여러 서버(소프트웨어 프로세스)가 있음 • 각 서버마다 포트가 할당됨 • 포트- 데이타 송수신에 사용되는 네트워크 출입구 • 클라이언트가 서버와 통신하기 위해서는 서버의 ip주소와 포트번호를 알아야 함 • 클라이언트가 보내는 매 패킷마다 서버의 ip주소와 포트번호가 들어 있음 강원대학교
자바의 소켓(Socket) • 포트(port)를 프로그램 안에서 제어할 수 있게 함 • 자바에서는 TCP, UDP 통신을 위한 각각 별도의 소켓 제공 • TCP의 경우에는 서버 소켓, 클라이언트 소켓이 따로 존재 • UDP의 경우에는 하나의 소켓만 존재 강원대학교
소켓과포트 포트 소켓 서버소켓 서버 클라이언트 서버 혹은 클라이언트 강원대학교
네트워킹의 종류 • TCP 네트워킹 • 신뢰성이 있는 연결지향적 통신 프로토콜 • 데이타가 전송 도중 소실될 경우 재전송할 수 있다. • 전송 순서대로 데이타가 도착된다. • UDP 네트워킹 • 신뢰성이 없는 비 연결지향적 통신 프로토콜 • 데이타가 전송 도중 소실될 수 있다. • 전송 순서대로 데이타가 도착되지 않을 수도 있다. • 신뢰성이 없는 대신 전송 속도는 TCP 보다 빠르다. 강원대학교
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 강원대학교
TCP 프로그래밍 강원대학교
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.
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()));
강원대학교 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) {} } }
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 호스트에 대한 연결을 잃었습니다.
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()));
강원대학교 // 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) {} } }
Eclipse에서 서버를 종료시키는 방법 ① 콘솔 창 리스트를 보이게 하여 ② 서버가 돌고 있는 콘솔을 선택하고 ③ 서버를 종료시킴 ③ ① ② 강원대학교
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) {} } }
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()));
강원대학교 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) {} } }
ServerSocket s = new ServerSocket(8008); Socket socket = s.accept(); Multi-threaded 서버 작동 절차 서버 대기 서버 클라이언트 강원대학교