800 likes | 1.01k Views
Thread. Synchronize. 프로세스 ( Process ). 실행 시킨 하나의 프로그램 프로세스가 다른 프로세스를 생성 가능 부모 프로세스 ( Parent Process) 자식 프로세스 (Child Process) : 부모에 의해 생성된 Process Runtime Class 플랫폼에 종속 적인 시스템 함수 ( 응용 프로그램 ) 를 호출 할 수 있는 환경을 제공 하는 Class Process Class 실행 시킨 응용 프로그램의 프로세스를 관리 할 수 있는 Class. 프로세스 생성 방법.
E N D
Thread Synchronize
프로세스( Process ) • 실행 시킨 하나의 프로그램 • 프로세스가 다른 프로세스를 생성 가능 • 부모 프로세스( Parent Process) • 자식 프로세스(Child Process) : 부모에 의해 생성된 Process • Runtime Class • 플랫폼에 종속 적인 시스템 함수( 응용 프로그램 )를 호출 할 수 있는 환경을 제공 하는 Class • Process Class • 실행 시킨 응용 프로그램의 프로세스를 관리 할 수 있는 Class
프로세스 생성 방법 • Runtime 객체를 생성 • Runtime r1 = Runtime.getRuntime(); • Process 객체를 생성 • Process p1 = r1.exec("notepad.exe"); • 자식 프로세스가 죽을 때 가지 기다림 • p1.waitFor(); • 프로세스를 종료 • p1.destroy();
프로세스 생성 방법 import java.io.*; public class Ex001Process { public static void main( String arg[] ) { try { Runtime r1 = Runtime.getRuntime(); Process p1 = r1.exec("notepad.exe"); p1.waitFor(); //Thread.sleep(2000); //p1.destroy(); } catch(IOException e){} catch(InterruptedException e){} } }
쓰레드( Thread ) 란? 프로그램(Process)을 구성 하고 있는 실행 단위이다. 실행될 명령어들의 연속이다. 여러 개의 쓰레드를 지원. ( 멀리 쓰레딩 ) 쓰레드는 우선 순위를 갖는다. 쓰레드 마다 서로 다른 일을 동시에 수행 하는 것처럼 보인다. Process main() 사용자 입력 및 서버로 전달 thread1 서버에서 전달되는 데이터 수신 thread2 비디오 재생
Thread의 Process 점유 thread1 thread2 시간의 경과 thread3 thread1 thread2 thread3
자바 Thread 와 OS Thread ( P.460 ) M-1 자바 가상 머신 자바 응용 프로그램 Thread1 Thread2 OS Process Thread1
자바 Thread 와 OS Thread 1-1 ( Windows 계열 ) 자바 가상 머신 자바 응용 프로그램 Thread1 Thread2 OS Process Thread1 Thread2
자바 Thread 와 OS Thread M-N( Solaris ) 자바 가상 머신 자바 응용 프로그램 Thread1 Thread2 Thread3 OS Process Thread1 Thread2
Thread • 메인 Thread • 자바 가상 머신이 실행될 때 발생 하는 Thread • 메인 Thread가 실행 되는 자바 응용 프로그램의 main() 메서드를 호출 한다. • 데몬 Thread • 데몬 Thread를 만든 Thread가 종료하고 자식 Thread가 모두 종료 되면 자신도 종료 • 데몬 Thread가 생성한 Thread는 데몬 Thread이다. • 유저 Thread • 자신을 만든 Thread에 종속 되지 않는 수명을 가진다. • 한정된 시간 동안 수행되는 Thread 선언
Thread 생성 방법 Thread Class를 상속 하여 쓰레드를 만든다. class MyThread extends Thread { public void run() { ..... } } Runnable 인터페이스를 구현하여 쓰레드를 만든다. class MyThread implements Runnable { ..... }
Thread Class 상속 • Thread Class를 상속 하여 Class를 작성 한다. • run() method 가 반드시 정의 되어야 한다. • Thread가 수행할 작업을 정의 한다. • Thread class의 하위 class에 대한 Instance를 생성 한다. • MyThread t = new MyThread(); • Thread를 시작 한다. • start() method 사용하여 시작 한다.( t.start(); ) • run() method가 실행 된다. • run() method의 실행이 끝나면 리턴 하게 되고 Thread가 종료 한다. • run() method의 반복적 실행을 원하면 while문을 이용하여 무한루프를 수행 하면 된다.
Thread Class 상속 public class Ex002Thread extends Thread { public void run() { System.out.println("Thread다"); } public static void main( String arg[] ) { Ex002Thread t1 = new Ex002Thread(); t1.start(); System.out.println("나는 main() 이다."); } }
Runnable 인터페이스 구현 • Runnable interface를 구현 한다. • run() method 가 반드시 정의 되어야 한다. • Thread가 수행할 작업을 정의 한다. • Runnable interface를 구현한 class의 instance를 생성한다. • MyThread t1 = new Mythread(); • Thread class의 instance 를 생성한다. 이때 생성자의 argument로 Runnable interface를 구현한 class의 instance를 넘겨 준다.(Thread 생성) • Thread t = new Thread(t1); • Thread를 시작 한다. • start() method 사용하여 시작 한다.( t.start(); ) • run() method가 실행 된다. • run() method의 실행이 끝나면 리턴 하게 되고 Thread가 종료 한다.
Runnable 인터페이스 구현 public class Ex003Thread implements Runnable { public void run() { System.out.println("Thread다"); } public static void main( String arg[] ) { Ex003Thread t = new Ex003Thread(); Thread t1 = new Thread(t); t1.start(); System.out.println("나는 main() 이다."); } }
Thread를 쭉 실행 public class Ex004Thread extends Thread { public void run() { while(true) { System.out.println("Thread다"); } } public static void main( String arg[] ) { Ex004Thread t1 = new Ex004Thread(); t1.start(); System.out.println("나는 main() 이다."); } }
Thread의 종료 및 대기 • Thread는 run() method가 수행 되는 동안 계속 살아 있다. • Thread의 종료 • stop() method 사용 ( t.stop(); ) • ThreadDeath 예외 발생 ( run() method에서 예외 처리 필요 ) • Thread 대기 • sleep() method 사용 ( t.sleep(2000); ) • 1/1000 초 단위로 정의 ( 2000으로 정의시 2000/1000 => 2초 ) • InterruptedException 정의 • Thread 대기(II) • join() method의 사용 ( t.join(); ) • 지정한 Thread가 죽을 때 까지 현재 Thread를 멈춤 • InterruptedException 정의
Thread의 종료 및 대기 public class Ex005Thread extends Thread { public void run() { while(true) { System.out.println("Thread다"); } }
Thread의 종료 및 대기 public static void main( String arg[] ) { Ex005Thread t1 = new Ex005Thread(); t1.start(); System.out.println("나는 main() 이다."); try { Thread.sleep(1); }catch(InterruptedException ie){} t1.stop(); } }
Thread의 종료 및 대기(II) public class Ex006Thread extends Thread { public void run() { for(int i = 1; i < 10 ; i++) { System.out.println("Thread다"); } }
Thread의 종료 및 대기(II) public static void main( String arg[] ) { Ex006Thread t1 = new Ex006Thread(); t1.start(); System.out.println("나는 main() 이다."); try { t1.join(); }catch(InterruptedException ie){} System.out.println("나는 main() 이다. II"); } }
Thread의 종료 (3) • InterruptedException 사용 • interrupt() method를 이용하여 InterruptedException 을 발생 시킨다. public class Ex0061Thread extends Thread{ public void run(){ try{ while(true){ System.out.println("Thread다"); Thread.sleep(10); } } catch(InterruptedException ie){ System.out.println("Thread 종료"); } }
Thread의 종료 및 대기(3) public static void main( String arg[] ) { Ex0061Thread t1 = new Ex0061Thread(); t1.start(); System.out.println("나는 main() 이다."); try { Thread.sleep(10); t1.interrupt(); }catch(InterruptedException ie){} System.out.println("나는 main() 이다. II"); } }
Thread의 종료 (4) - 추천 • 멤버 변수를 이용한다. • Thread의 종료를 원할 때 멤버 변수의 값을 변경 한다. public class Ex0062Thread extends Thread { private boolean threadRun = true; public void run() { while(threadRun) { System.out.println("Thread다"); } }
Thread의 종료 (4) public void setThreadRun(boolean threadRun) { this.threadRun = threadRun; } public static void main( String arg[] ) { Ex0062Thread t1 = new Ex0062Thread(); t1.start(); System.out.println("나는 main() 이다."); try{ Thread.sleep(1); t1.setThreadRun(false); }catch(InterruptedException ie){} System.out.println("나는 main() 이다. II"); } }
Thread의 종료 및 대기 (5) • suspend() / resume() 사용 • Thread가 얼마 동안 Block되어야 할지 모르는 경우 사용 • suspend()를 호출 하면 Block • resume()를 호출 해야지만 Runnable public class Ex0063Thread extends Thread { public void run() { try{ while(true) { System.out.println("Thread hahahaha"); sleep(500); } } catch(InterruptedException e){} }
Thread의 종료 및 대기 (5) public static void main(String[] args) { Ex0063Thread obj = new Ex0063Thread(); System.out.println("Thread 전"); obj.start(); try { Thread.sleep(1000); System.out.println("suspend"); obj.suspend(); Thread.sleep(1000); System.out.println("resume"); obj.resume(); Thread.sleep(1000); } catch(InterruptedException e ){} } }
Blocked Newborn Dead Runnable Running Thread의 상태 ( P. 442 ) Thread는 생성,실행,멈춤,소멸의 상태를 가진다.
Thread의 상태 • 생성 • Thread를 생성하고 실행 하기 바로 직전의 상태 • Runnable • start() method를 호출한 상태 • Running • CPU를 할당 받아 실제 실행 되는 상태 • Blocked • suspend,sleep,wait method 호출 또는 i/o 작업 시 발행 • suspend -> resume() , wait() -> notify() , sleep -> 주어진 시간 후 , i/o - > 작업을 끝 • Dead • run() method 종료 • stop() method 호출
Thread 스케줄링 • 선점형 스케줄링 • 자바 런타임 스케줄러는 우선 순위가 높은 Thread를 실행 시켜 준다. • 더 높은 우선 순위의 Thread가 실행 가능 하게 되면 그 Thread를 실행 • 타임 슬라이싱( Time-Slicing OR Round-Robin ) • 우선 순위가 같은 여러 Thread가 동시가 실행 되면 일정 시간동안 돌아가면서 실행 • 우선 순위 • MIN_PRIORITY : 1 , 가장 낮은 우선 순위 • NORM_PRIORITY : 5 , 기본 우선 순위 • MAX_PRIORITY : 10 , 가장 높은 우선 순위
Thread 스케줄링 void setName() : Thread 이름을 정의 String getName() : Thread 이름을 반환 Thread currentThread() : 현재 수해중인 Thread를 리턴 int getPriority() : 우선 순위 값을 얻음 void setPriority(int) : 우선 순위 값을 설정
Thread 스케줄링 public class Ex007Thread extends Thread { public void run() { while(true) { System.out.println("getName() = " + getName()); try { Thread.sleep(100); } catch(InterruptedException e){} } }
Thread 스케줄링 public static void main( String arg[] ) { Ex007Thread t1 = new Ex007Thread(); Ex007Thread t2 = new Ex007Thread(); Thread.currentThread().setPriority( Thread.MAX_PRIORITY ); t1.setName("a"); t2.setName("b"); t1.start(); t2.start(); System.out.println(" a의 우선 순위 = " + t1.getPriority()); System.out.println(" b의 우선 순위 = " + t2.getPriority());
Thread 스케줄링 try { Thread.sleep(100); t1.setPriority( Thread.MAX_PRIORITY ); System.out.println(" a의 우선 순위 = " + t1.getPriority()); System.out.println(" b의 우선 순위 = " + t2.getPriority()); Thread.sleep(100); t1.setPriority( Thread.MIN_PRIORITY ); System.out.println(" a의 우선 순위 = " + t1.getPriority()); System.out.println(" b의 우선 순위 = " + t2.getPriority()); Thread.sleep(100); }catch(InterruptedException ie){} t1.stop(); t2.stop(); ......................................
Daemon Thread 모든 Thread가 종료하면 자동으로 종료하는 Thread 보통 다른 Thread에게 서비스를 하는 기능을 구현 보통 무한 루프로 구성된다. 데몬 Thread가 생성한 Thread는 데몬 Thread이다. void setDaemon(boolean) method를 이용하여 만들어 준다. boolean isDaemon() method로 데몬 Thread여부를 확인 할 수 있다.
Daemon Thread ............................... public static void main( String arg[] ) { Ex008DaemonThread t1 = new Ex008DaemonThread(); Ex008DaemonThread t2 = new Ex008DaemonThread(); t1.setDaemon(true); t1.start(); t2.start(); try { Thread.sleep(100); }catch(InterruptedException ie){} t2.stop(); } ...............................
Daemon Thread가 생성한 Thread class Ex009DaemonThread2 extends Thread { public void run() { while(true) { System.out.println("getName() = " + getName() + " : " + isDaemon()); try { Thread.sleep(50); } catch(InterruptedException e){} } } }
Daemon Thread가 생성한 Thread public class Ex009DaemonThread extends Thread { public void run() { Ex009DaemonThread2 t2 = new Ex009DaemonThread2(); t2.start(); while(true) { System.out.println("getName() = " + getName() + " : " + isDaemon()); try { Thread.sleep(50); } catch(InterruptedException e){} } } ....................................
Constructor Summary ThreadGroup(Stringname) ThreadGroup(ThreadGroupparent, Stringname) Thread Group Thread 또는 Thread Group을 포함 할 수 있다. Thread를 그룹으로 관리 가능 하게 한다. 모든 Thread는 Thread Group에 포함 되어있다. Thread Group의 생성 ThreadGroup tg = new ThreadGroup(“group”) Thread t = new Thread(tg, obj)
Thread Group • 시스템 Thread Group • 최상위 Thread Group • 자바 응용 프로그램이 시작 되면 • 시스템 Thread그룹의 멤버로 main Thread 그룹을 만든다. • main Thread를 만들어 main Thread그룹에 포함 시킨다. • main Thread는 main method를 호출 한다. • 사용자가 생성한 Thread는 main Thread그룹의 멤버가 된다.
Thread Group public class Ex010ThreadGroup implements Runnable { String threadName ; public Ex010ThreadGroup(String name) { threadName = name; } public void run() { while(true) { System.out.println("threadName = " + threadName); try { Thread.sleep(50); } catch(InterruptedException e){} } }
Thread Group public static void main( String arg[] ) { ThreadGroup tg1 = new ThreadGroup("MyGroup"); Ex010ThreadGroup t1 = new Ex010ThreadGroup("a"); Ex010ThreadGroup t2 = new Ex010ThreadGroup("b"); Thread t1Thread = new Thread( tg1 , t1 ); Thread t2Thread = new Thread( tg1 , t2 ); t1Thread.start(); t2Thread.start(); System.out.println("Thread.activeCount = " + Thread.activeCount() ); try { Thread.sleep(100); tg1.stop(); }catch(InterruptedException ie){} } }
Thread간의 공유 데이터 Thread 들이 하나의 데이터를 공유 Thread 1 i++ i++ Thread 2 static int i = 0; Thread 3 i++
Thread간의 공유 데이터 public class Ex011Thread extends Thread { static int i = 0; //int i = 0; public void run() { //int i = 0; while(true) { System.out.println("getName() = " + getName() + " : i = " + i++ ); try { Thread.sleep(50); } catch(InterruptedException e){} } }
Thread간의 공유 데이터 public static void main( String arg[] ) { Ex011Thread t1 = new Ex011Thread(); Ex011Thread t2 = new Ex011Thread(); t1.start(); t2.start(); try { Thread.sleep(100); }catch(InterruptedException ie){} t1.stop(); t2.stop(); } }
10 + 10 Thread 10 20 공유자원 10 10 20 20 20 10 + 10 Thread 10 20 Thread간의 공유 데이터 Thread 들이 서로 데이터를 변경 하려고 할 때 문제가 발생 할 수 있다.
10 + 10 Thread 10 20 synchronized 공유자원 10 10 20 20 20 synchronized Thread 20 Thread간의 공유 데이터
Thread간의 공유 데이터 stackPointer 5(END) 4 3 2 1 Thread A B Stack B B A Thread A B A
Thread간의 공유 데이터 stackPointer 5(END) 3 2 1 4 Thread B A Stack B B A Thread A B A