35
자바 네트워크 프로그래밍 (OCJP 국제공인자격 취득 중심) 충북대학교 최민

자바 네트워크 프로그래밍contents.kocw.net/KOCW/document/2014/Chungbuk/choimin/11.pdf프로그램의 실행 흐름으로 프로그램 카운터(Program counter), CPU 레지스터

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

자바 네트워크 프로그래밍 (OCJP 국제공인자격 취득 중심)

충북대학교

최민

2 SCJP 5.0 대비 강좌

머리글 및 출제기준 쓰레드의 개념 쓰레드를 생성하고 활용하는 방법 쓰레드 현재 실행되고 있는 프로세스의 실행 흐름

자바에서는 멀티 쓰레드(multi-thread)기능을 제공하는데, 여기에서 멀티 쓰레드란 하나의 프로그램 안에서 여러 작업을 동시에 처리할 수 있다는 이야기

OCJP시험에는 쓰레드를 생성하는 방법, 실행중인 쓰레드 동기화, 교착상태, 쓰레드의 특징에 관하여 출제

3 SCJP 5.0 대비 강좌

출제기준 1. 쓰레드를 생성하는데 있어서 java.lang.Thread 클래스를 사용하는 방법과 Runnable Interface를 사용하는 방법을 알아보고 쓰레드의 인스턴스를 만들어 실행할 수 있어야 합니다. 2. 쓰레드가 실행중에 존재할 수 있는 상태(Ready, Running, Waiting, Terminated, New)를 알고 각 상태로의 전이가 일어나는 상황을 이해합니다. 3. 하나 이상의 쓰레드가 동시에 공유데이터에 접근할 때 발생할 수 있는 문제와 이를 해결하기 위한 동기화 방법으로 wait(), notify(), notifyAll() 등의 메소드를 이용하여 프로그래밍 할 수 있어야 합니다. 또, wait(), notify(), notifyAll() 메소드가 수행될 때 쓰레드간 상호 작용 및 쓰레드와 오브젝트 lock 사이에 일어나는 상호작용을 정의할 수 있어야 합니다. 4. 교착상태에 빠지는 상황을 이해합니다. 5. 쓰레드 실행의 우선순위를 조정하는 방법 및 yield() 메소드의 사용에 관하여 숙지합니다.

4 SCJP 5.0 대비 강좌

쓰레드 기초 쓰레드 프로그램의 실행 흐름으로 프로그램 카운터(Program counter), CPU 레지스터 세트(register set), 스택(stack)으로 구성

쓰레드가 실행될때 각 쓰레드들은 프로그램 코드를 공유하며 이런 실행흐름(쓰레드)이 동시에 하나 이상 존재

한 프로그램 내에서 동시에 두가지 이상의일을 수행하는 것처럼 인식

프로세스는 결국 하나의 쓰레드를 가진 프로그램

5 SCJP 5.0 대비 강좌

멀티 쓰레드 이들 3개의 쓰레드들은 같은 프로그램 코드를 공유 각 쓰레드가 가진 지역변수들(그림에서 변수 a 혹은 b)은 공유하지 않습니다.

지역변수의 값에 따라서 if문을 실행하는 쓰레드/실행하지 않는 쓰레드도 있을 것이고 while문을 실행하는 쓰레드/실행하지 않는 쓰레드도 존재할 것임

즉, 그림에서 코드를 실행하는 경우 수직선으로 실행하지 않는 경우 수직선을 오른쪽으로 이동하여 표시하였음

6 SCJP 5.0 대비 강좌

쓰레드 기초 멀티쓰레드 프로그램의 예 네트웍을 통하여 새로운 데이터를 전송받으면서

이미 전송받은 데이터를 화면에 표시하는 웹 브라우저나,

배경 음악이 나오면서 화면에서 그림이 움직이는 게임

자바에서는 쓰레드 관련 클래스만 이용하면 간단하게 멀티쓰레드 프로그램을 작성할 수 있음

7 SCJP 5.0 대비 강좌

쓰레드 기초 이와같은 쓰레드의 장점을 잘 활용하기 위해서는 멀티쓰레드 프로그래밍에 관한 특징

(1) 자바에서 쓰레드를 생성하는 두가지 방법,

(2) 쓰레드가 같은 메모리 공간을 공유하기 때문에 발생할 수 있는 비일관성(inconsistency)문제 해결을 위한 쓰레드 동기화 (synchronization) 방법

(3) 쓰레드가 실행 중 존재할 수 있는 여러 가지 상태 및 이들 사이의 상태전이 현상과 그 원인을 파악

8 SCJP 5.0 대비 강좌

Thread 클래스 쓰레드의 생성 및 실행 자바에서 쓰레드는 Thread 클래스의 객체로 표현되며, 쓰레드를 생성하는 방법은 두 가지가 존재합니다.

java.lang.Thread 클래스를 상속받아 생성하는 방법

java.lang.Runnable 인터페이스(interface)를 구현하는 방법

9 SCJP 5.0 대비 강좌

Thread 클래스 java.lang.Thread 클래스를 상속받아 생성하는 방법

Thread 클래스를 상속받는 방법 : Thread 클래스가 가지는 여러 메소드들을 오버라이드(override)하여 구현

① Thread 클래스를 상속받은 클래스의 run() 메소드를 오버라이드하여 실제로 쓰레드가 실행할 코드를 기술함

② 부모클래스인 Thread 클래스의 생성자를 호출(이 과정을 생략하더라도 다른 클래스에서처럼 기본 생성자 Thread()를 자동으로 호출됨)

③ Thread 클래스로부터 상속받은 start() 메소드를 호출.

10 SCJP 5.0 대비 강좌

Thread 클래스 실제로, Thread 클래스를 상속받는 MyThread 클래스는 public 접근제한자의 run() 메소드 가짐 Run()메소드 내에 MyThread에서 수행할 프로그램 코드를 기재합니다.

11 SCJP 5.0 대비 강좌

Thread 클래스

MyThread 클래스를 정의한 뒤에는 이 클래스를 인스턴스화하고 쓰레드 실행을 위해 start() 메소드 호출

class MyThread extends Thread { public void run() { // MyThread에서 수행할 내용 } }

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

12 SCJP 5.0 대비 강좌

Thread 클래스 java.lang.Runnable 인터페이스(interface)를 구현하는 방법 쓰레드로 정의하고자 하는 클래스가 Thread 클래스 이외의 다른 클래스를 이미 상속받고 있다면 ? 그리고 그 클래스의 주된 목적이 쓰레드와는 관계없는 클래스라면? 자바에서는 다중 상속을 허용하지 않으므로

Runnable 인터페이스를 구현하는 클래스를 정의하며 run()메소드를 오버라이드

이 클래스의 인스턴스를 생성해서 start() 메소드를 호출.

13 SCJP 5.0 대비 강좌

Thread 클래스 Runnable 인터페이스는 다음과 같이 정의. Runnable 인터페이스는 단지 run() 함수 하나만 포함 . run() 메소드는 쓰레드 실행의 경로를 나타내므로 쓰레드는 run() 메소드의 실행이 끝날 때 종료.

public interface Runnable { public void run(); }

14 SCJP 5.0 대비 강좌

Thread 클래스 Runnable 인터페이스를 구현하여 쓰레드를 사용하는 방법은 일반적으로 다음과 같은 절차를 따릅니다. ① Runnable 인터페이스를 구현, 즉, 쓰레드에서 실행될 run() 메소드에 코드를 기술. ② 쓰레드 클래스의 객체가 생성되며, Runnable 인터페이스를 구현하는 클래스 객체를 Thread class의 인자로 전달 ③ 쓰레드를 실행하기 위하여 start() 메소드를 호출합니다. Runnable 인터페이스를 구현하는 MyThread 예

15 SCJP 5.0 대비 강좌

Thread 클래스 앞에서의 Thread 클래스를 상속받는 방법과 큰 차이 없음 extends Thread 대신 implements Runnable의 형태로 상속이 아닌 인터페이스를 구현 쓰레드를 인스턴스화 할때 차이점 존재

class MyThread implements Runnable { public void run() { // MyThread에서 수행할 내용 } }

16 SCJP 5.0 대비 강좌

Thread 클래스

MyThread mt = new MyThread(); Thread t = new Thread(mt); t.start(); 혹은 Thread t = new Thread(new MyThread()); t.start();

17 SCJP 5.0 대비 강좌

Thread 클래스 Thread 객체를 생성할 때 Runnable 인터페이스를 구현하는 클래스 객체를 인자로 전달 차후 이 쓰레드에 대한 컨트롤을 할 필요가 있을 때 쓰레드 객체를 지역변수 mt로 가리키도록 함 반면, 쓰레드를 생성하고 실행하기만 하면 되는 경우 익명 객체(anonymous object)로 생성하여 Thread 클래스의 인스턴스화에 사용

18 SCJP 5.0 대비 강좌

기본 예제 예제

for 반복문을 사용하여 숫자를 0부터 4까지 증가시키며 출력하는 기능을 하는 쓰레드를 생성하고 실행하는 프로그램

다른 동작을 원한다면 이 run() 메소드를 재정의하면 됨.

class MyThread extends Thread { private int num; public MyThread() { super(); num = 0; }

19 SCJP 5.0 대비 강좌

기본 예제 public void run() { try { for (int i=0; i<5; i++) { System.out.println(getName() + ": " + num); Thread.sleep((int)(Math.random() * 1000)); num++; } } catch (InterruptedException e) { System.out.println(getName() + " interrupted..."); } System.out.println("End..."); } }

20 SCJP 5.0 대비 강좌

기본 예제 현재 num 값을 출력한 뒤 Thread.sleep() 메소드를 사용하여 임의시간동안 쓰레드가 sleep 함 참고로, Thread.sleep() 메소드를 사용할 때 반드시 InterruptedException에 대한 처리를 해주어야 함.

getName()메소드 Thread의 이름을 얻어오는 것으로 기본적으로 0, 1, ... 값을 가짐

부모클래스의 생성자를 호출할 때 쓰레드 이름을 넘겨주면 각 쓰레드에 고유한 이름을 부여할 수 있음

다음은 MyThread 쓰레드를 객체로 인스턴스화 하고 이를 실행하는 ThreadTest 클래스의 main 메소드 사례

21 SCJP 5.0 대비 강좌

기본 예제 Thread 클래스를 상속받아 만들어진 MyThread 클래스를 인스턴스화 하고 이를 실행함.

public class ThreadTest { public static void main(String[] args) { Thread t1 = new MyThread(); Thread t2 = new MyThread(); t1.start(); t2.start(); } }

22 SCJP 5.0 대비 강좌

기본 예제

Thread-0: 0 Thread-1: 0 Thread-0: 1 Thread-1: 1 Thread-0: 2 Thread-1: 2 Thread-0: 3 Thread-0: 4 Thread-1: 3 Thread-1: 4 End... End...

23 SCJP 5.0 대비 강좌

기본 예제 for 반복문을 사용하여 숫자를 0부터 4까지 증가시키며 출력하는 기능을 하는 쓰레드

Runnable 인터페이스를 사용하여 구현됨

class MyThread2 implements Runnable { private int num; public MyThread2() { super(); num = 0; } public void run() { for (int i=0; i<5; i++) { System.out.println(num); num++; } System.out.println("End..."); } }

24 SCJP 5.0 대비 강좌

기본 예제 쓰레드를 하나만 생성하고 실행 클래스 선언부분

MyThread2 클래스를 Runnable 인터페이스를 구현.

이 쓰레드의 객체를 생성하고 실행하는 ThreadTest2 클래스

25 SCJP 5.0 대비 강좌

기본 예제

public class ThreadTest2 { public static void main(String[] args) { MyThread2 mt1 = new MyThread2(); Thread t1 = new Thread(mt1); t1.start(); } }

26 SCJP 5.0 대비 강좌

기본 예제 실행 결과

0 1 2 3 4 End...

27 SCJP 5.0 대비 강좌

실전문제 Concerning Thread, which of the following statement or

statements are true? (multiple choice) □ a) Threads created from the same class all finish together. □ b) A thread can be created only by subclassing

java.lang.Thread. □ c) The execution of a specific Thread can be suspended

indefinitely if required. □ d) Uncoordinated changes to shared data by multiple threads

may result in the data being read, or left, in a inconsistent state.

28 SCJP 5.0 대비 강좌

쓰레드의 종류(사용자 쓰레드, 데몬 쓰레드)를 변경가능 Thread.setDaemon() 메소드를 사용

Thread.setDaemon() 메소드의 원형. 이 메소드는 현재의 쓰레드를 사용자 쓰레드로 할 것인지 데몬 쓰레드로 할 것인지 설정함

주의사항 이 메소드는 쓰레드의 실행이 시작되기 전에 호출되어야 함.

public final void setDaemon(boolean on);

29 SCJP 5.0 대비 강좌

쓰레드 상태 쓰레드는 생성된 후 종료되기까지 여러 조건이나 사용자의 메소드 호출에 따라 여러가지 상태로 존재 쓰레드의 start() 메소드를 호출하였다고 해서, 바로 CPU를 할당받아 실행에 들어가는 것은 아님 쓰레드가 상태 전이도.

30 SCJP 5.0 대비 강좌

쓰레드 상태

31 SCJP 5.0 대비 강좌

쓰레드 상태 쓰레드가 처음 생성 경우 new 상태, 종료되는 경우 terminated 상태 그 외 ready, running, waiting 상태

running : CPU가 현재 이 쓰레드를 실행하고 있음을 나타냅니다.

waiting : running 상태에서 wait() 메소드, sleep()메소드, 혹은 I/O 요청으로 인하여 블록된 경우입니다.

ready : waiting 상태에 존재하던 쓰레드는 곧바로 running 상태로 들어가지 않습니다.

일단 ready 상태에서 다른 쓰레드들이 waiting상태로 빠지기까지 대기하다가 CPU를 할당 받음

yield() 메소드 : 현재 실행중인 쓰레드를 ready 상태로 돌리고 자신에게 할당된 CPU를 자발적으로 포기. 따라서, 다른 쓰레드에게 CPU를 할당받아 실행할 수 있는 기회를 주고 자신은 다음 차례를 기다립니다.

32 SCJP 5.0 대비 강좌

기본 예제 Thread.yield() 메소드에 대한 사용법을 숙지하기 위한 예제 두개의 쓰레드가 각각 0부터 4까지의 숫자를 출력 그러나 각 반복(iteration)에서 Thread.yield() 메소드를 통해 자신의 CPU 사용권한을 다른쓰레드에 양도하므로 두개의 쓰레드가 한번씩 번갈아 가며 실행함. 사실상 사용자 레벨 쓰레드에서는 명시적으로 Thread.yield() 메소드를 통하여 CPU를 자발적으로 포기하지 않으면 우리가 원하는 정도의 병렬성(concurrency)를 얻기 힘듭니다. 뿐만 아니라 SCJP 시험에서도 Thread.yield() 메소드의 사용법에 관해서는 중요한 비중으로 다루어지고 있으므로 반드시 숙지

33 SCJP 5.0 대비 강좌

기본 예제

class YieldTestThread extends Thread{ private int num; public YieldTestThread() { super(); num = 0; } public void run() { for (int i=0; i<5; i++) { System.out.println(getName() + ": " + num); Thread.yield(); num++; } System.out.println("End..."); } }

34 SCJP 5.0 대비 강좌

기본 예제 다음은 이 쓰레드 클래스를 생성하고 시작하기 위한 메인 메소드를 포함하고 있는 TrheadStatus 클래스.

public class ThreadStatus { public static void main(String args[]) throws InterruptedException { YieldTestThread et1 = new YieldTestThread(); et1.start(); YieldTestThread et2 = new YieldTestThread(); et2.start(); } }

35 SCJP 5.0 대비 강좌

기본 예제 실행 결과

Thread-0: 0 Thread-1: 0 Thread-0: 1 Thread-1: 1 Thread-0: 2 Thread-1: 2 Thread-0: 3 Thread-1: 3 Thread-0: 4 Thread-1: 4 End... End...