Presentation is loading. Please wait.

Presentation is loading. Please wait.

Power Java 제16장 스레드(Thread).

Similar presentations


Presentation on theme: "Power Java 제16장 스레드(Thread)."— Presentation transcript:

1 Power Java 제16장 스레드(Thread)

2 스레드는 동시에 여러 개의 프로그램을 실행하는 효과를 냅니다.
이번 장에서 학습할 내용 스레드는 동시에 여러 개의 프로그램을 실행하는 효과를 냅니다. 스레드의 개요 스레드의 생성과 실행 스레드 상태 스레드의 스케줄링 스레드간의 조정

3 병렬 처리 병렬작업(Multi-tasking) 프로세스의 다중화
여러 개의 작업을 동시에 실행시켜서 컴퓨터 시스템의 성능을 높이기 위한 기법 운영 체제가 CPU의 시간을 쪼개서 (Time-slicing) 각 작업에 할당하여 작업들이 동시에 수행되는 것처럼 보이게 함

4 스레드란? 다중 스레딩(multi-threading)은 하나의 프로그램이 동시에 여러 가지 작업을 할 수 있도록 하는 것
Thread = Light-weight Process 각각의 작업은 스레드(thread)라고 불린다. 병렬 작업의 아이디어를 프로세스 안으로 가져온 것 하나의 프로세스가 동시에 여러 작업을 하도록 함

5 스레드란?

6 프로세스와 스레드 프로세스(process): 자신만의 데이터를 가진다.
프로세스의 메모리 공간은 분리되어 있다. Java에서는 자바 가상 머신 자체가 하나의 프로세스가 됨 스레드(thread): 동일한 데이터(shared data)를 공유한다. 쓰레드 생성은 프로세스 생성보다 OS입장에서 부담이 적다. 프로세스의 모든 자원을 공유한다. 자바 가상 머신에서 가장 먼저 실행되는 쓰레드는 main() 쓰레드

7 프로세스와 스레드

8 스레드를 사용하는 이유 웹 브라우저에서 웹 페이지를 보면서 동시에 파일을 다운로드할 수 있도록 한다.
워드 프로세서에서 문서를 편집하면서 동시에 인쇄한다. 게임 프로그램에서는 응답성을 높이기 위하여 많은 스레드를 사용한다. GUI에서는 마우스와 키보드 입력을 다른 스레드를 생성하여 처리한다. 웹 서비스 스레드 웹문서 요청 웹문서 전송 웹 서버 각 클라이언트 당 웹 서비스 스레드 생성 웹 클라이언트 웹 서버 시스템

9 JVM과 자바 응용프로그램, 스레드의 관계 JVM JVM JVM 운영체제 운영체제 운영체제 하드웨어 하드웨어 하드웨어
자바 응용 프로그램 자바 응용 프로그램 자바 응용 프로그램1 자바 응용 프로그램2 자바 응용 프로그램3 자바 스레드 자바 스레드 자바 스레드 JVM JVM JVM 운영체제 운영체제 운영체제 하드웨어 하드웨어 하드웨어 JVM은 오직 하나의 자바 응용프로그램만 실행 JVM은 여러 개의 자바 응용프로그램 실행 불가 하나의 응용프로그램은 여러 개의 스레드 가질 수 있음 자바 응용 프로그램 1 통신 자바 응용 프로그램 2 JVM JVM 운영체제 하드웨어 두 개의 자바 응용프로그램이 동시에 실행시키고자 하면 두 개의 JVM을 이용하고 응용프로그램은 서로 소켓 등을 이용하여 통신

10 자바 스레드와 JVM 자바응용프로그램 각 스레드의 스레드 코드는 응용프로그램 내에 존재함 JVM이 스레드를 관리함
객체 객체 객체 객체 각 스레드의 스레드 코드는 응용프로그램 내에 존재함 스레드 코드 1 스레드 코드 2 스레드 코드 3 스레드 코드 4 스레드 정보1 스레드 정보2 스레드 정보3 스레드 정보4 JVM이 스레드를 관리함 스레드가 몇 개인지? 스레드 코드의 위치가 어디인지? 스레드의 우선순의는 얼마인지? JVM 운영체제(Windows or Linux) 하드웨어(PC or Embedded Board, 워크스테이션 등) 현재 하나의 JVM에 의해 4 개의 스레드가 실행 중이며 그 중 스레드 2가 JVM에 의해 스케쥴링되어 실행되고 있음

11 중간 점검 문제 1. 스레드와 프로세스의 결정적인 차이점은 무엇인가?
프로세스는 독자적으로 실행이 가능한 환경으로 일반적으로 완전한 자기만의 자원을 가진다. 스레드는 프로세스 안에 존재하여 메모리와 파일을 포함하여 프로세스의 모든 자원을 공유한다. 2. 스레드를 사용해야만 하는 프로그램을 생각하여 보자. 게임프로그램 3. 다중 스레딩에서 발생할 수 있는 문제에는 어떤 것들이 있을까? 추측하여 보라. 데이터 공유  동기화 (Synchronization) 문제

12 스레드 생성과 실행 스레드는 Thread 클래스가 담당한다.

13 스레드를 생성하는 방법 Thread 클래스를 상속하는 방법 스레드 생성 방법 Runnable 인터페이스를 구현하는 방법
클래스가 이미 다른 클래스로부터 상속 받는 경우. 다중 상속이 가능하게 하기 위해 사용.

14 Thread 클래스를 상속하는 방법 java.lang 패키지 1. Thread 클래스를 상속받는 서브클래스를 작성한다.
run() 메소드를 구현한다. (일종의 쓰레드의 main() 메소드) 2. main() 메소드 내부에서 작성한 서브클래스의 객체를 생성하여 그 객체에게 start() 메소드를 호출한다.

15 Runnable 인터페이스를 구현하는 방법
Thread 객체 = 일꾼 Runnable 객체 = 작업의 내용

16 Runnable 인터페이스를 구현하는 방법

17 어떤 방법이 좋은가? 자바에서 다중 상속이 불가능한 것을 감안한다면 Runnable 인터페이스를 사용하는 것이 좋다.
Runnable 인터페이스를 사용하면 고수준의 스레드 관리 API도 사용할 수 있다. Runnable 구현 Thread 상속

18 예제 #1

19 예제 #2 TestThread1.java

20 중간 점검 문제 1. 스레딩을 담당하는 클래스의 이름은? 2. Thread를 상속받는 방법의 문제점은 무엇인가?
 다중 상속 불가 (Runnable 인터페이스 사용)

21 스레드 상태 생성 준비 대기 완료

22 생성 상태와 실행 가능 상태 생성 상태 Thread 클래스를 이용하여 새로운 스레드를 생성
start()는 생성된 스레드를 시작 stop()은 생성된 스레드를 멈추게 한다. 실행 가능 상태 (준비) 스레드가 스케줄링 큐에 넣어지고 스케줄러에 의해 우선순위에 따라 실행

23 실행 중지 상태 실행 가능한 상태에서 다음의 이벤트가 발생하면 실행 중지 상태로 된다.
스레드나 다른 스레드가 suspend()를 호출하는 경우 스레드가 wait()를 호출하는 경우 스레드가 sleep()을 호출하는 경우 스레드가 입출력 작업을 하기 위해 대기하는 경우

24 강제적인 종료

25 중간 점검 문제 1. Thread의 run() 메소드의 역할은?
2. Thread의 start(), stop() 메소드의 역할은? 3. 어떤 일이 발생하면 스레드가 실행 중지 상태로 가는가?

26 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) born 상태
ready (=runnable) 상태 Thread 객체에 start() 메소드를 호출한 상태 아직 CPU에 스케줄링되어 실행되지는 않는다 born ready running dead blocked sleeping waiting start() CPU 자원 점유 I/O interrupt I/O complete sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() 1) 정상 만료 2) 우선순위에 밀림 3) yield() 1) stop() 2) 정상종료 stop() stop() stop() stop()

27 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) running 상태
CPU에 스케줄링되어 실행을 하는 상태 일정시간이 지나면 ready 상태로 자동으로 돌아간다. yield() 메소드가 호출되면 ready 상태로 돌아간다. sleep() 메소드가 호출되면 sleeping 상태로 전이된다. born ready running dead blocked sleeping waiting start() CPU 자원 점유 I/O interrupt I/O complete sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() 1) 정상 만료 2) 우선순위에 밀림 3) yield() 1) stop() 2) 정상종료 stop() stop() stop() stop()

28 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) sleeping 상태
running 상태에서 sleep(long millis)가 호출되면 sleeping으로 전이됨 Timer가 작동되어 지정된 시간동안 잠시 쉬는 상태 Timer가 만료되면 ready 상태로 전이된다. born ready running dead blocked sleeping waiting start() CPU 자원 점유 I/O interrupt I/O complete sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() 1) 정상 만료 2) 우선순위에 밀림 3) yield() 1) stop() 2) 정상종료 stop() stop() stop() stop()

29 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) waiting 상태
running 상태에서 wait()이 호출되면 waiting 상태로 전이됨 누군가에 의하여 notify()나 notifyall()이 호출될 때까지 이 상태에 존재 notify()나 notifyall()이 호출되면 ready 상태로 전이됨 born ready running dead blocked sleeping waiting start() CPU 자원 점유 I/O interrupt I/O complete sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() 1) 정상 만료 2) 우선순위에 밀림 3) yield() 1) stop() 2) 정상종료 stop() stop() stop() stop()

30 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) blocked 상태 dead 상태
입출력(I/O) 등의 인터럽트가 걸리면 잠시 blocked 상태로 전이됨 해당 인터럽트가 끝나면 자동으로 ready 상태로 전이됨 dead 상태 ready, waiting, sleeping, blocked 상태 어느 곳에서도 stop() 이 호출되면 dead 상태로 들어감 다시는 스케줄링되지 못하게 되어 CPU 자원을 더 이상 이용 못함 born ready running dead blocked sleeping waiting start() CPU 자원 점유 1) stop() 2) 정상종료 I/O interrupt I/O complete sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() 1) 정상 만료 2) 우선순위에 밀림 3) yield() stop() stop() stop() stop()

31 쓰레드 상태(세부사항) Thread State Diagram (Life Cycle) blocked 상태 dead 상태
입출력(I/O) 등의 인터럽트가 걸리면 잠시 blocked 상태로 전이됨 해당 인터럽트가 끝나면 자동으로 ready 상태로 전이됨 dead 상태 ready, waiting, sleeping, blocked 상태 어느 곳에서도 stop() 이 호출되면 dead 상태로 들어감 다시는 스케줄링되지 못하게 되어 CPU 자원을 더 이상 이용 못함 born ready running dead blocked sleeping waiting start() CPU 자원 점유 1) stop() 2) 정상종료 I/O interrupt I/O complete 1) 정상 만료 2) 우선순위에 밀림 3) yield() sleep() (=timed wait) wait() sleep expire 1) notify() 2) notifyAll() stop() stop() stop() stop()

32 쓰레드 상태 정상 종료 run() 메소드의 모든 작업이 끝나서 종료되는 경우 강제 종료
stop() 메소드를 사용하여 종료하는 경우 public void run() { for (int i = 0; i < 10; i++) { System.out.println(name + ": " + i); } public static void main(String[] args) { MyThread my = new MyThread(); my.start(); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { } my.stop();

33 스레드 스케줄링

34 쓰레드의 스케줄링 스케줄링 (Scheduling)
ready 상태에 있는 여러 쓰레드 중 어떤 쓰레드에게 CPU 자원을 할당하여 수행시킬 것인가를 결정하는 작업 Round-robin 방식 사용 각 쓰레드에게 균등하게 CPU 시간을 분배하는 것 우선 순위 기반 스케줄링 Thread 클래스에 정적으로 정의된 MIN_PRIORITY(=1)와 MAX_PRIORITY(=10) 사이 값으로 우선 순위를 할당 받을 수 있다. 스케줄러는 현재 수행 가능한 쓰레드 중에서 가장 우선 순위가 높은 쓰레드를 먼저 수행시킬 가능성이 크다. MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); MyThread my3 = new MyThread(); my1.setPriority(Thread.MIN_PRIORITY); // my1.setPriority(1); my2.setPriority(Thread.NORM_PRIORITY); // my1.setPriority(5); my3.setPriority(Thread.MAX_PRIORITY); // my1.setPriority(10);

35 쓰레드의 스케줄링 선점형 (Preemptive) 스케줄링
더 높은 우선 순위를 가지는 Thread가 ready 상태로 들어오면 현재 수행되던 Thread는 강제로 ready 상태로 가고 우선 순위가 높은 새로운 Thread가 (가능하면) 먼저 수행되는 방식 정리 The chosen thread will run until one of the following conditions is true: 1) a higher priority thread becomes "ready" 2) its run() method exits 3) yield() method is called 4) on systems that support time-slicing, its time allotment has expired

36 쓰레드의 스케줄링 스케줄링 관련 예제 ScheduleTest.java public class ScheduleTest {
public static void main(String[] args) { for(int i = 0; i < 5; i++) new MyCounting("Thread of Low Priority", Thread.MIN_PRIORITY).start(); new MyCounting("Thread of High Priority", Thread.MAX_PRIORITY).start(); } class MyCounting extends Thread { String name; double d; int countDown = 5; public MyCounting(String name, int priority) { this.name = name; setPriority(priority); public void run() { for(int i = 1; i < ; i++) d = d + (Math.PI + Math.E) / (double)i; System.out.println(name + ": done"); if(--countDown == 0) return;

37 쓰레드의 스케줄링 sleep(long millis)
현재 쓰레드의 실행을 지정된 시간 (millis)동안 중단하여 sleeping 상태에 들아가게 한다. CPU 자원을 양보하는 효과적인 수단 SleepTest.java class Counting3 extends Thread { String name; public Counting3(String name) { this.name = name; } public void run() { for (int i = 0; i < 10; i++) { System.out.println(name + ": " + i); try { sleep(1000); } catch (InterruptedException e) { Sleep 도중에 인터럽트가 발생하면 InterruptedException 이 발생 발생된 InterruptedException에 대한 상황처리는 개발자의 몫

38 쓰레드의 스케줄링 sleep(long millis) SleepTest.java public class SleepTest {
public static void main(String[] args) { Counting3 t1 = new Counting3("Thread 1"); Counting3 t2 = new Counting3("Thread 2"); Counting3 t3 = new Counting3("Thread 3"); t1.start(); t2.start(); t3.start(); }

39 쓰레드의 스케줄링 Thread.sleep(long millis) main() 등에서 쉽게 사용할 수 있는 정적 메소드
CountDown.java public class CountDown { public static void main(String args[]) throws InterruptedException { for (int i = 10; i >= 0; i--) { Thread.sleep(1000); System.out.println(i); }

40 쓰레드의 스케줄링 (예) public class JavaExam { public static void main(String[] args) { MyThread worker = new MyThread(); worker.start(); for (int num = 0;num < 20;num++) { try { Thread.sleep(50); } catch (InterruptedException e) { ; } System.out.print("Java "); } class MyThread extends Thread { public void run() { try { Thread.sleep(30); } catch (InterruptedException e) { ; } System.out.print("자바 ");

41 동기화 동기화(synchronization): 한 번에 하나의 스레드 만이 공유 데이터를 접근할 수 있도록 제어하는 것이 필요
예제: 공유되는 데이터

42 은행 계좌

43 사용자

44 BankTest 클래스 공유된 객체:account Why?

45 스레드 one의 입금은 없어진다. 이후 스레드 one이 출금하고, two 가 출금하면?
오류가 발생하는 원인 오류가 발생하는 여러 가지의 경우가 있지만 그 중의 하나는 다음과 같다. balance one two 스레드 one의 입금은 없어진다. 이후 스레드 one이 출금하고, two 가 출금하면? account

46 동기화 문제 (Synchronization)
하나의 스레드가 공유 데이터를 사용하면 다른 스레드가 사용하지 못하게 해야 합니다. (critical section)

47 ……… 동기화 동기화(Synchronization) - synchronized method 수행 스레드A 스레드B
시간 t lock을 얻는다 t lock을 요청하지만 이미 t 사용중이므로 기다린다 t3 t4 t5 t lock을 양보한다 t lock을 얻는다 t8 t9 synchronized method 스레드A 스레드B ……… ……………….. 임계영역 문장들

48 동기화 메소드 자바가 제공하는 동기화 방법 ~kky/JavaT/Lect2011/ThreadB/BankTest.java 복사 후 실행 (오류 check)  동기화 해 볼 것 한순간에 하나의 스레드만을 허용

49 스레드간의 조정 만약 두개의 스레드가 데이터를 주고 받는 경우에 발생

50 Buffer 클래스 생산자와 소비자가 공유 P C data put get

51 생산자 클래스 error

52 소비자 클래스

53 테스트 클래스 ~kky/JavaT/Lect2011/ThreadC/CoordinationTest.java 생산이 너무 빠름 !!
소비가 너무 빠름!!

54 Deadlock(교착 상태) 교착 상태(膠着狀態, deadlock)란 두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 가리킨다. 예를 들어 하나의 사다리가 있고, 두 명의 사람이 각각 사다리의 위쪽과 아래쪽에 있다고 가정한다. 이때 아래에 있는 사람은 위로 올라 가려고 하고, 위에 있는 사람은 아래로 내려오려고 한다면, 두 사람은 서로 상대방이 사다리에서 비켜줄 때까지 하염없이 기다리고 있을 것이고 결과적으로 아무도 사다리를 내려오거나 올라가지 못하게 되듯이, 전산학에서 교착 상태란 다중 프로그래밍 환경에서 흔히 발생할 수 있는 문제이다.

55 Deadlock(교착 상태)

56 생산자/소비자 문제 해결 ~kky/JavaT/Lect2011/ThreadC/Deadlock/CoordinationTest.java ~kky/JavaT/Lect2011/ThreadC/Deadlock/Buffer.java

57 wait()와 notify()

58 스레드 사이의 통신 wait() 메소드와 notify(), notifyAll() 메소드의 동작 wait() 스레드 t1
대기상태를 깨운다 wait() notify() notifyAll()

59 생산자/소비자 문제에 적용

60 생산자/소비자 문제 해결

61 생산자/소비자 문제 해결

62 중간 점검 문제 1. wait()와 notify() 메소드는 왜 필요한가? 2. wait()는 어떤 역할을 하는가?

63 스레드 예(검색 프로그램) SearchTask.java public void run() {
BufferedReader br = null; try { URL u = new URL(url); br = new BufferedReader(new InputStreamReader(u.openStream())); String s = ""; while((s = br.readLine()) != null) { if (s.indexOf(target) != -1) { System.out.println(url + " , " + target + " 찾았습니다."); return; } } System.out.println(url + " , " + target + " 없습니다."); } catch(Exception e ) { e.printStackTrace(); } finally { try { if (br != null) br.close(); catch(Exception ignore) { } } } } import java.net.*; import java.io.*; /** * URL로 지정되는곳에서 TARGET을 찾습니다. */ public class SearchTask implements Runnable { private String url; private String target; * String url : 검색할 URL * String target : 검색할 대상 public SearchTask(String url,String target) { this.url = url; this.target = target; }

64 스레드 예(검색 프로그램) BasicConcurrentSearch.java SearchTask.java
public class BasicConcurrentSearch { public static void main(String[] args) { if (args.length != 1) { System.out.println("java BasicConcurrentSearch person"); System.exit(1); } String target = args[0]; Runnable r1 = new SearchTask(" new Thread(r1).start(); Runnable r2 = new SearchTask(" new Thread(r2).start(); Runnable r3 = new SearchTask(" new Thread(r3).start(); Runnable r4 = new SearchTask(" new Thread(r4).start(); BasicConcurrentSearch.java SearchTask.java ~kky/JavaT/Lect2011/Thread3_Search/…

65 Lab. #1 공유된 자원 BankAccount 객체 account에 대한 두 스레드의 예를 작성하고 실행 결과를 분석하자.
~kky/JavaT/Lect2011/ThreadB/BankTest.java

66 Lab. #1 BankAccount 클래스의 메소드를 동기화하여 공유된 자료에 대한 접근에 문제가 발생하지 않게 수정하라.

67 Lab. #2 생산자와 소비자 문제 프로그램을 돌려보고 결과를 분석하라.
수정된 Buffer 클래스를 사용하여 문제를 해결하라.(wait와 notifyAll 사용) 문제점이 발생하나? 해결해 보라!!! ~kky/JavaT/Lect2011/ThreadC/…

68 Lab. #3

69 Create a BankAccount object Create two sets of threads:
Sample Application Create a BankAccount object Create two sets of threads: Each thread in the first set repeatedly deposits $100 Each thread in the second set repeatedly withdraws $100 deposit and withdraw have been modified to print messages: public void deposit(double amount) { System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; }

70 Sample Application The result should be zero, but sometimes it is not Normally, the program output looks somewhat like this: Depositing 100.0, new balance is Withdrawing 100.0, new balance is 0.0 Depositing 100.0, new balance is Depositing 100.0, new balance is Withdrawing 100.0, new balance is Withdrawing 100.0, new balance is 0.0 But sometimes you may notice messed-up output, like this: Depositing 100.0Withdrawing 100.0, new balance is 100.0, new balance is

71 Scenario to Explain Non-zero Result: 경쟁조건
A deposit thread executes the lines System.out.print("Depositing " + amount); double newBalance = balance + amount; The balance field is still 0, and the newBalance local variable is 100 The deposit thread reaches the end of its time slice and a withdraw thread gains control The withdraw thread calls the withdraw method which withdraws $100 from the balance variable; it is now -100 The withdraw thread goes to sleep Continued

72 Scenario to Explain Non-zero Result: Race Condition
The deposit thread regains control and picks up where it left off; it executes: System.out.println(", new balance is " + newBalance); balance = newBalance; The balance is now 100 instead of 0 because the deposit method used the OLD balance

73 Corrupting the Contents of the balance Field

74 경쟁조건 Occurs if the effect of multiple threads on shared data depends on the order in which they are scheduled It is possible for a thread to reach the end of its time slice in the middle of a statement It may evaluate the right-hand side of an equation but not be able to store the result until its next turn public void deposit(double amount) { balance = balance + amount; System.out.print("Depositing " + amount + ", new balance is " + balance); } Race condition can still occur: balance = the right-hand-side value

75 ch18/unsynch/BankAccountThreadTester.java Continued 01: /**
02: This program runs 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 = 100; 12: final int THREADS = 100; 13: 14: for (int i = 1; i <= THREADS; i++) 15: { 16: DepositRunnable d = new DepositRunnable( 17: account, AMOUNT, REPETITIONS); 18: WithdrawRunnable w = new WithdrawRunnable( 19: account, AMOUNT, REPETITIONS); 20: Continued

76 ch18/unsynch/BankAccountThreadTester.java (cont.)
21: Thread dt = new Thread(d); 22: Thread wt = new Thread(w); 23: 24: dt.start(); 25: wt.start(); 26: } 27: } 28: } 29:

77 ch18/unsynch/DepositRunnable.java Continued 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: { 15: account = anAccount; 16: amount = anAmount; 17: count = aCount; 18: } 19: Continued

78 ch18/unsynch/DepositRunnable.java (cont.)
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: 33: private static final int DELAY = 1; 34: private BankAccount account; 35: private double amount; 36: private int count; 37: }

79 ch18/unsynch/WithdrawRunnable.java Continued 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: } 19: Continued

80 ch18/unsynch/WithdrawRunnable.java (cont.)
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: }

81 ch18/unsynch/BankAccount.java Continued 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: */ 19: public void deposit(double amount) 20: { Continued

82 ch18/unsynch/BankAccount.java (cont.)
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: } 38: 39: /** 40: Gets the current balance of the bank account. 41: @return the current balance 42: */ Continued

83 ch18/unsynch/BankAccount.java (cont.)
43: public double getBalance() 44: { 45: return balance; 46: } 47: 48: private double balance; 49: }

84 ch18/unsynch/BankAccount.java (cont.)
Output: Depositing 100.0, new balance is Withdrawing 100.0, new balance is Depositing 100.0, new balance is Withdrawing 100.0, new balance is Withdrawing 100.0, new balance is Depositing 100.0, new balance is Withdrawing 100.0, new balance is Withdrawing 100.0, new balance is 300.0 ~kky/JavaT/Lect2011/ThreadB2/unsync/…  입금 스레드, 출금 스레드, 입금 스레드, 출금 스레드를 생성하고 run!!!  synchonized를 사용하여 동기화하여 보라.

85 Lab. #4 wait()와 notifyAll() 사용하여 해결 시도

86 Q & A


Download ppt "Power Java 제16장 스레드(Thread)."

Similar presentations


Ads by Google