Java 10장. 다중 스레드 public class SumTest { public static void main(String a1[]) { int a, b, sum; a = Integer.parseInt(a1[0]); b = Integer.parseInt(a1[1]); sum = a + b ; // 두 수를 더하는 부분입니다 System.out.println("두수의 합은 " + sum + "입니다"); }
학습목표 스레드의 개념과 스레드 생명주기에 관해 학습한다. 스레드 생성 방법에 관해 학습한다. 스레드의 우선순위에 관해 학습한다. 다중 스레드의 시작과 종료에 관해 학습한다. 다중 스레드의 사용 방법에 관해 학습한다. 스레드 사이의 통신 방법에 관해 학습한다.
목차 section 1 스레드 개요 section 2 Thread 클래스와 스레드 생명주기 3-2 Runnable 인터페이스 이용 section 4 스레드 우선순위 section 5 스레드의 시작과 종료 section 6 스레드 동기화(Synchronization) section 7 스레드 사이의 통신
다수 개의 CPU를 가진 컴퓨터에서 다중 스레드의 실행 1 스레드 개요 다중 스레드(multi thread) 하나의 프로그램 내에서 다수 개의 스레드가 동시에 수행되는 형태 다수 개의 CPU를 가진 컴퓨터에서 다중 스레드의 실행 307 page
한 개의 CPU를 가진 컴퓨터에서 다중 스레드의 실행 1 스레드 개요 한 개의 CPU를 가진 컴퓨터에서 다중 스레드의 실행 307 page
Thread 클래스 형식 2 Thread 클래스와 스레드 생명주기 java.lang 패키지에 라이브러리 클래스로 제공 Thread(String s) Thread(Runnable r) Thread(Runnable r, String s) 형식
스레드 클래스의 메소드 2 Thread 클래스와 스레드 생명주기 메소드 이름 설명 static void sleep(long msec) throws InterruptedException msec에 지정된 밀리초(milliseconds) 동안 대기 static void sleep(long msec, int nsec) msec에 지정된 밀리 초 +nsec에 지정된 나노초(nanoseconds) 동안 대기 String getName() 스레드의 이름을 반환 void setName(String s) 스레드의 이름을 s로 설정 void start() 스레드를 시작시킨다. run() 메소드를 호출 final int getPriority() 스레드의 우선순위를 반환 final void setPriority(int p) 스레드의 우선순위를 p 값으로 설정 boolean isAlive() 스레드가 실행 가능 상태, 실행상태, 대기상태에 있으면 true를 그렇지 않으면 false를 반환 void join() throws InterruptedException 스레드가 끝날 때까지 대기 void run() 스레드가 실행할 부분을 기술하는 메소드. 하위 클래스에 서 오버라이딩되어야 한다. void suspend() 스레드가 일시 정지된다. resume()에 의해 다시 시작될 수 있다. void resume() 일시 정지된 스레드를 다시 시작시킨다.
2 Thread 클래스와 스레드 생명주기 스레드의 생명주기 310 page
스레드는 생성되어 종료될 때까지 5가지의 상태 2 Thread 클래스와 스레드 생명주기 생성 상태 실행 가능 상태 실행 상태 대기상태 종료
3 스레드의 생성과 사용 3-1 Thread 클래스 이용 Thread(java.lang.Thread) 클래스로부터 직접 상속받아 스레드 특징을 가지는 클래스를 생성하여 스레드를 사용하는 방법 class ThreadA extends Thread { ......... public void run() { .... } ....... Thread 클래스로부터 상속 상위 클래스인 Thread 클래스의 run() 메소드를 오버라이딩하여 스레드가 수행하여야 하는 문장들을 기술한다. ThreadA ta = new ThreadA(); ta.start();
3 스레드의 생성과 사용 3-2 Runnable 인터페이스 이용 스레드의 특성을 가져야 하는 클래스가 이미 다른 클래스로부터 상속을 받고 있다면 Runnable 인터페이스를 이용 public interface Runnable { public void run(); } class RunnableB extends Applet implements Runnable { ......... public void run() { ........ } Runnable 인터페이스에 정의된 run() 메소드를 오버라이딩하여 스레드가 수행할 문장들을 기술한다.
3-2 Runnable 인터페이스 이용 인터페이스를 이용하여 생성된 클래스로부터 스레드 객체를 생성하는 예 3 스레드의 생성과 사용 3-2 Runnable 인터페이스 이용 인터페이스를 이용하여 생성된 클래스로부터 스레드 객체를 생성하는 예 RunnableB rb = new RunnableB(); Thread tb = new Thread(rb); tb.start(); 객체 rb 생성 rb를 매개변수로 하여 스레드 객체 tb를 생성 스레드 시작 RunnableB rb = new RunnableB(); new Thread(rb).start(); 스레드 객체를 생성하여 바로 시작
3-2 Runnable 인터페이스 이용 실습예제 3 스레드의 생성과 사용 ThreadFromThread.java 01 02 03 04 05 06 07 08 09 10 11 12 13 class ThreadTest extends Thread { public void run() { for (int i=1 ; i<=10 ; i++) { System.out.println("재미있는 자바 :" + i); } public class ThreadFromThread { public static void main(String args[]) { ThreadTest t = new ThreadTest(); t.start(); Thread 클래스로부터 상속받아 클래스 작성 run() 메소드 오버라이딩 스레드 특성을 가진 객체 생성 스레드 시작(run() 메소드 호출)
3-2 Runnable 인터페이스 이용 프로그램 설명 3 스레드의 생성과 사용 00 : 스레드의 특성을 가진 클래스를 작성하기 위해 Thread 클래스로부터 상속을 받아 클래스를 작성하였다. Thread 클래스로부터 상속받았기 때문에 이 클래스의 객체에서는 Thread 클래스의 모든 메소드를 사용할 수 있다. 00~00 : run() 메소드는 Thread 클래스가 가지고 있는 메소드이다. run() 메소드를 오버라이딩하여 스레드가 해야할 일을 기술한다. run() 메소드는 start() 메소드에 의해 자동 호출되는 메소드이다. 00 : 스레드 객체를 생성한다. 00 : 객체의 start() 메소드를 호출하여 스레드를 시작시킨다. start() 메소드는 Thread 클래스에서 제공되는 메소드로서 run() 메소드를 호출한다. 이때 실행되는 run() 메소드는 Thread 클래스에서 제공된 run() 메소드가 아니라, 하위 클래스에 오버라이딩된 run() 메소드가 수행된다.
3 스레드의 생성과 사용 3-2 Runnable 인터페이스 이용
3-2 Runnable 인터페이스 이용 실습예제 3 스레드의 생성과 사용 ThreadFromRunnable.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 class RunnableTest implements Runnable { public void run() { for (int i=1 ; i<=10 ; i++) { System.out.println("재미있는 자바 :" + i); } public class ThreadFromRunnable { public static void main(String args[]) { RunnableTest r = new RunnableTest(); Thread t = new Thread(r); t.start(); Runnable 인터페이스를 포함하는 클래스 작성 run() 메소드 오버라이딩 객체 생성 생성된 객체를 이용하여 스레드 객체 생성 스레드 시작(run() 메소드 호출)
3-2 Runnable 인터페이스 이용 프로그램 설명 3 스레드의 생성과 사용 01~05 : 이미 클래스가 다른 클래스로부터 상속을 받고 있다고 가정하여, Runnable 인터페이스를 포함하는 클래스를 작성하였고, Runnable 인터페이스에 선언된 run() 메소드를 오버라이딩하여 스레드가 해야 할 기능을 정의하였다. 그러나 이 클래스는 아직 완벽한 스레드의 특성이 아닌 Runnable 인터페이스의 특성만(run()메소드만 가짐) 가지고 있는 상태이다. 10 : 인터페이스를 포함한 클래스로부터 객체를 생성한다. 그러나 이 객체는 Runnable 인터페이스의 특성만 가지게 된다. 11 : Runnable 특성을 가진 객체를 이용하여 스레드 객체를 생성한다. 스레드 클래스는 Runnable 형의 객체를 이용하여 객체를 생성할 수 있는 생성자를 제공하고 있다. 12 : 스레드를 시작시킨다.
3-2 Runnable 인터페이스 이용 실습예제 3 스레드의 생성과 사용 DoubleThread.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 class ThreadTest1 extends Thread { public ThreadTest1(String str) { setName(str); } public void run() { for (int i=1 ; i<=10 ; i++) { System.out.println(i + getName()); System.out.println("끝" + getName()); public class DoubleThread { public static void main(String args[]) { ThreadTest1 t1 = new ThreadTest1 (" : 배우기 쉬운 자바"); ThreadTest1 t2 = new ThreadTest1 (" : 배우기 어려운 자바"); t1.start(); t2.start(); Thread 클래스로부터 상속받아 클래스 작성 스레드의 이름을 설정 번호와 스레드 이름을 출력 이름이 다른 두 개의 스레드 객체 생성 스레드 동시 실행 스레드 동시 실행
3-2 Runnable 인터페이스 이용 프로그램 설명 3 스레드의 생성과 사용 01 : 스레드의 특성을 가진 클래스를 작성하기 위해 Thread 클래스로부터 상속을 받아 클래스를 작성하였다. 03 : 생성자에서 스레드의 이름을 설정하였다. setName() 메소드는 Thread 클래스에서 제공되는 메소드로 스레드의 이름을 설정하는 메소드이다. 07 : getName() 메소드를 사용하여 스레드의 이름을 출력한다. 14~17 : 하나의 스레드 클래스로부터 두 개의 스레드 객체를 생성한다. 18, 19 : 두 개의 스레드를 시작시킨다. 두 개의 시작 문장이 순차적으로 수행되는 개념이 아니고 스레드의 특성을 가진 객체이기 때문에 동시에 수행된다.
3 스레드의 생성과 사용 3-2 Runnable 인터페이스 이용 실행결과 1
3 스레드의 생성과 사용 3-2 Runnable 인터페이스 이용 실행결과 2
스레드에 우선순위를 부여하여 우선순위가 높은 스레드에 실행의 우선권을 주어 실행 4 스레드 우선순위 스레드에 우선순위를 부여하여 우선순위가 높은 스레드에 실행의 우선권을 주어 실행 setPriority() Thread 클래스에는 스레드에 우선순위를 부여하는 메소드가 제공 static final int MAX_PRIORITY ← 우선순위 값으로 10을 가진다. static final int MIN_PRIORITY ← 우선순위 값으로 1을 가진다. static final int NORM_PRIORITY ← 우선순위 값으로 5를 가진다.
실습예제 4 스레드 우선순위 ThreadPriority.java 01 02 03 04 05 06 07 08 09 10 11 class PriorityTest extends Thread{ public PriorityTest(String str){ setName(str); } public void run(){ for(int i=1; i<=5; i++){ System.out.println( i + getName() + " 우선순위 : " + getPriority() ); getPriority() 메소드로 우선순위 출력
실습예제 4 스레드 우선순위 ThreadPriority.java 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class ThreadPriority { public static void main(String args[]){ PriorityTest t1 = new PriorityTest(" : 첫번째 스레드"); PriorityTest t2 = new PriorityTest(" : 두번째 스레드"); PriorityTest t3 = new PriorityTest(" : 세번째 스레드"); int priority_t1 = Integer.parseInt(args[0]); int priority_t2 = Integer.parseInt(args[1]); t1.setPriority(priority_t1); t2.setPriority(priority_t2); t3.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); t3.start(); } 우선순위 설정
4 스레드 우선순위 프로그램 설명 07, 08 : getPriority() 메소드를 이용하여 스레드가 가진 우선순위를 출력하였다. 19~21 : 매개변수로 받은 두 개의 값과 Thread 클래스에서 제공되는 상숫값(MIN_PRIORITY)을 이용하여 스레드의 우선순위를 설정(setPriority()) 하였다.
5 스레드의 시작과 종료 다중 스레드를 가진 프로그램의 실행 흐름 323 page
실습예제 5 스레드의 시작과 종료 DoubleThread1.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 class DoubleThreadTest1 extends Thread { public DoubleThreadTest1(String str) { setName(str); } public void run() { for (int i=1 ; i<=3 ; i++) { System.out.println(i + getName()); System.out.println("끝" + getName()); public class DoubleThread1 { public static void main(String args[]) { DoubleThreadTest1 t1 = new DoubleThreadTest1(" : 배우기 쉬운 자바"); DoubleThreadTest1 t2 =
실습예제 5 스레드의 시작과 종료 DoubleThread1.java 17 18 19 20 21 22 23 new DoubleThreadTest1(" : 배우기 어려운 자바"); System.out.println("***** 스레드 시작 전 *****"); t1.start(); t2.start(); System.out.println("***** 스레드 종료 후 *****"); } 스레드 시작 전에 출력
5 스레드의 시작과 종료 프로그램 설명 18~21 : 스레드를 시작하기 전에 “***** 스레드 시작 전 *****”을 출력하고 스레드 시작 문장다음에 “***** 스레드 종료 후 *****”를 출력하였다. 프로그램의 실행결과를 보면 두개의 문장이 처음에 출력됨을 알 수 있다. 이 결과는 스레드를 시작시키는 문장이 동시에 실행된다는 의미이다. 스레드 시작 문장이 먼저 출력된 것은 스레드가 종료되기를 기다리지 않고 프로그램은 계속 수행이 된다는 의미이다.
실습예제 5 스레드의 시작과 종료 DoubleThread2.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 class DoubleThreadTest2 extends Thread { public DoubleThreadTest2(String str) { setName(str); } public void run() { for (int i=1 ; i<=3 ; i++) { System.out.println(i + getName()); System.out.println("끝" + getName()); public class DoubleThread2 { public static void main(String args[])throws Exception { DoubleThreadTest2 t1 = new DoubleThreadTest2 (" : 배우기 쉬운 자바"); DoubleThreadTest2 t2 = new DoubleThreadTest2 join() 메소드 사용을 위해 예외 처리
실습예제 5 스레드의 시작과 종료 DoubleThread1.java 17 18 19 20 21 22 23 24 25 (" : 배우기 어려운 자바"); System.out.println("***** 스레드 시작 전 *****"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("***** 스레드 종료 후 *****"); } join() 메소드 수행 스레드 종료 후에 실행
5 스레드의 시작과 종료 프로그램 설명 13 : main() 메소드 내에서 join() 메소드를 사용하기 위해 예외를 처리하였다. 예외 처리에서 지정된 Exception 클래스는 대부분의 예외 관련 클래스를 하위 클래스로 가지고 있다. Exception을 지정함으로써 하위 클래스와 관련된 모든 예외를 처리할 수 있다. throws 절을 이용하여 발생된 예외를 JVM(main() 메소드를 호출하였기 때문에)에 넘기는 예외 처리를 하고 있다. 21, 22 : 각 스레드가 끝나기를 기다렸다가, 모든 스레드가 종료되기를 기다린다. 스레드가 종료되면 다음 문장으로 제어가 이동된다.
5 스레드의 시작과 종료
6 스레드 동기화(Synchronization) 임계영역(critical section) 다수 개의 스레드가 접근 가능한 영역 한순간에는 하나의 스레드만 사용할 수 있는 영역 자바에서는 임계영역 지정을 위한 synchronized 메소드를 제공
6 스레드 동기화(Synchronization) 다중 스레드 환경에서의 synchronized 메소드 실행 329 page
6 스레드 동기화(Synchronization) 실습예제 330 page
6 스레드 동기화(Synchronization) 실습예제 TVContribution.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 class Account { private int total = 0; synchronized void deposit() { total = total + 1000; } int gettotal() { return total; class Customer extends Thread { Account same_a; Customer(Account a, String s) { same_a = a; setName(s); public void run() { for(int i = 0; i < 200 ; i++) { System.out.println(getName() + " : " + i +"번째"); 1000원을 더하는 동기화 메소드 선언 스레드 이름과 Account 객체를 설정
6 스레드 동기화(Synchronization) 실습예제 TVContribution.java 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 same_a.deposit(); if (same_a.gettotal() >= 500000) break; } public class TVContribution { public static void main(String args[])throws Exception { Account same_account = new Account(); Customer donator1 = new Customer(same_account,"1번째 성금자"); Customer donator2 = new Customer(same_account,"2번째 성금자"); Customer donator3 = new Customer(same_account,"3번째 성금자"); Customer donator4 = new Customer(same_account,"4번째 성금자"); Customer donator5 = new Customer(same_account,"5번째 성금자"); 반복문을 돌며 deposit() 메소드 호출 전체금액이 50만원 보다 크면 반복문을 벗어남 Account 클래스로부터 객체 생성 생성자에서 동일한 객체를 지정함 (5개의 스레드가 same_account 객체 공유)
6 스레드 동기화(Synchronization) 실습예제 TVContribution.java 37 38 39 40 41 42 43 44 45 46 47 48 49 50 donator1.start(); donator2.start(); donator3.start(); donator4.start(); donator5.start(); donator1.join(); donator2.join(); donator3.join(); donator4.join(); donator5.join(); System.out.println("성금 총액은 : " + same_account.gettotal()); }
6 스레드 동기화(Synchronization) 프로그램 설명 03~05 : Account 클래스에 deposit() 동기화 메소드를 선언하였다. 이 클래스로부터 생성된 객체는 5개의 스레드에 의해 공유된다. 즉 5개의 스레드가 하나의 Account 클래스 객체를 공유하면서 동기화 메소드인 deposit()을 경쟁적으로 호출하게 된다. 동기화 메소드는 동시에 호출되어도 하나의 한순간에는 스레드만 실행할 수 있고, 나머지 스레드는 대기하게 된다. 12~15 : 스레드 클래스이다. 생성자에서 스레드의 이름과 Account 객체를 설정하고 있다. 이미 5개의 스레드가 같은 Account 객체를 사용하여(27-31라인 참조) 스레드 객체를 생성하였기 때문에 5개의 스레드가 Account 객체를 공유하게 된다. 19~20 : 스레드 클래스의 run() 메소드 내에 200번을 반복하며 deposit() 메소드를 호출하도록 하였다. 총 금액이 50만 원이 넘으면 반복을 중단하도록 하였다. 26 : Account 클래스로부터 하나의 객체 same_account를 생성하였다. 27~36 : 하나의 same_account 객체를 이용하여 5개의 스레드 객체를 생성하였다. 결국 5개의 스레드 객체는 하나의 same_account 객체를 공유하는 형태이다.
6 스레드 동기화(Synchronization) 실행결과
6 스레드 동기화(Synchronization) 실행결과
스레드 사이의 통신을 위한 메소드를 java.lang.Object 클래스에 제공 7 스레드 사이의 통신 스레드 사이의 통신을 위한 메소드를 java.lang.Object 클래스에 제공 Object 클래스에서 제공되는 메소드 중 wait(), notify(), notifyAll() 메소드가 스레드 사이의 통신에 이용 wait() 메소드의 3가지 형태 void wait() throws InterruptedException void wait(long msec) throws InterruptedException void wait(long msec, int nsec) throws InterruptedException
wait() : 무한정 대기 상태에 들어가는 메소드 7 스레드 사이의 통신 wait() : 무한정 대기 상태에 들어가는 메소드 wait(long msec) : msec 밀리초 동안 대기하다 스스로 깨어나는 메소드 wait(long msec, int nsec) : msec 밀리초와 nsec 나노초 동안 대기하다 스스로 깨어나는 메소드 notify() : 대기 중인 스레드가 여러 개일 경우 그중에 하나의 스레드만을 깨운 notifyAll() 메소드 : 대기 중인 모든 스레드를 깨우는 것을 제외하고는 notify()와 같음 void notify() void notifyAll()
wait( ) 메소드와 notify( ), notifyAll( ) 메소드의 작동 7 스레드 사이의 통신 wait( ) 메소드와 notify( ), notifyAll( ) 메소드의 작동 335 page
예제 7 스레드 사이의 통신 ProducerConsumer.java 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 class Buffer { private int contents; private boolean available = false; public synchronized void put(int value) { while (available == true ) { try{ wait(); } catch (InterruptedException e) {} contents = value; System.out.println ("생산자########## : 생산 " + contents); notify(); available = true; public synchronized int get() { while (available == false ) { try { 생산자와 소비자가 공유하는 데이터(쌀)를 넣는 곳 번갈아가며 수행하기 위한 이진 변수 생산자가 가져다 놓는 동기화 메소드 이진 변수의 값에 따라 대기 여부 결정 데이터를 생산하고 대기 스레드를 깨운다 소비자가 데이터를 가져가는 동기화 메소드 이진 변수의 값에 따라 대기 여부 결정
예제 7 스레드 사이의 통신 ProducerConsumer.java 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 } catch (InterruptedException e) {} System.out.println ("소비자########## : 소비 " + contents); notify(); available = false; return contents; class Producer extends Thread { private Buffer b; public Producer(Buffer blank) { b = blank ; public void run() { for (int i = 1; i <= 10;i++) b.put(i); 값을 가져오고 대기 스레드를 깨운다 생산자와 스레드 클래스
예제 7 스레드 사이의 통신 ProducerConsumer.java 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 class Consumer extends Thread { private Buffer b; public Consumer(Buffer blank) { b = blank; } public void run() { int value = 0; for (int i = 1 ; i <= 10 ; i++ ) value = b.get(); public class ProducerConsumer { public static void main(String args[]) { Buffer buff = new Buffer(); Producer p1 = new Producer(buff); Consumer c1 = new Consumer(buff); p1.start() ; c1.start() ; 소비자 스레드 클래스 하나의 Buffer 객체 생성 동일한 Buffer 객체를 사용하여 스레드 객체 생성
7 스레드 사이의 통신 프로그램 설명 02 : 생산자와 소비자가 공유하는 데이터(쌀)를 넣는 곳으로 private 변수를 선언하였다. 이 변수를 이용하여 생산자는 숫자를 저장하고, 소비자는 저장된 숫자를 가져간다. 03 : 생산자와 소비자가 번갈아가며 수행하기 위한 이진 변수를 사용한다. 이 문제에서는 먼저 생산자가 생산을 해야 하므로 초깃값을 false로 지정한다. 04 : 생산자가 생산된 데이터를 가져다 놓는 동기화 메소드이다. 05~08 : 생산자가 데이터를 가져다 놓을 때 현재의 공유 변수의 값을 소비자가 소비했는지를 검사하는 부분이다. 이진 변수의 값에 따라 데이터를 출력할 것인지, 아니면 소비자가 가져갈 때까지 대기할 것인지가 결정된다. 14 : 이 부분은 데이터를 생산(출력)하고 소비자 스레드를 깨우는 부분이다. 소비자 스레드가 대기 상태에 있다면, 이 메소드의 수행으로 소비자 스레드가 다시 실행된다. 17 : 데이터를 소비하는 동기화 메소드를 선언한다.
7 스레드 사이의 통신 프로그램 설명 18~21 : 소비자가 데이터를 가져갈 때 현재의 공유 변수의 값을 생산했는지를 검사하는 부분이다. 이진 변수의 값에 따라 데이터를 가져갈 것인지, 아니면 생산자가 생산할 때까지 대기할 것인지가 결정된다. 26 : 이 부분은 데이터를 소비하고 생산자 스레드를 깨우는 부분이다. 생산자 스레드가 대 기 상태에 있다면, 이 메소드의 수행으로 생산자 스레드가 다시 실행된다. 31,41 : 생산자와 소비자 스레드 클래스이다. 각 클래스의 run() 메소드 내에서 반복적으로 put() 메소드와 get() 메소드를 호출하고 있다. 54 : 하나의 Buffer 객체를 생성한다. 55, 56 : 생산된 하나의 동일한 Buffer 객체를 사용하여 스레드 객체를 생산함으로써, 두 개의 스레드가 Buffer 객체를 공유하며 실행된다.
7 스레드 사이의 통신 실행결과
학습정리 스레드 개요 Thread 클래스와 스레드 생명주기 스레드의 생성과 사용 스레드는 실행 중인 프로세스라 할 수 있으며, 하나의 프로그램에 다수 개의 스레드를 실행시킬 수 있다. 한 개의 CPU를 가진 컴퓨터에서 스레드는 CPU에 의해 돌아가며 수행되게 된다. Thread 클래스와 스레드 생명주기 자바에서는 스레드를 지원하기 위해 Thread 클래스를 제공하고 있다. 스레드 클래스는 스레드를 지원하는 다양한 메소드를 가지고 있다. 스레드는 생성, 실행 가능 상태, 실행 상태, 대기 상태 등의 생명주기를 가지고 있다. 스레드의 생성과 사용 자바에서 스레드는 두 가지 방법으로 사용이 가능하다.
학습정리 스레드의 우선순위 스레드의 시작과 종료 Thread 클래스로부터 상속받아 스레드를 사용하는 방법과 Runnable 인터페이스를 포함하여 스레드 클래스를 사용하는 방법이 있으며, 현재의 클래스가 다른 클래스로부터 이미 상속을 받고 있는 경우에 Runnable 인터페이스를 이용하여 스레드를 작성한다. 스레드의 우선순위 각각의 스레드는 1~10 사이의 우선순위를 가질 수 있다. CPU는 실행 가능 상태의 스레드 중에서 우선순위가 높은 스레드를 먼저 수행한다. 스레드의 시작과 종료 다중 스레드를 가진 프로그램에서 start() 메소드에 의해 스레드가 시작되면, 프로그램의 흐름이 단일 흐름에서 다중 흐름으로 전환된다. 다중 스레드는 동시 수행되는 개념이므로 스레드가 수행을 마치고 다시 단일 흐름으로 프로그램을 실행시키기 위해서는 join() 메소드를 이용하여 흐름을 하나로 만들어야 한다.
학습정리 스레드 동기화 다수 개의 스레드가 임계영역을 수행하기 위해서는 synchronized 메소드를 사용해야 한다. synchronized 메소드는 한순간에 하나의 스레드만 실행할 수 있다. 한 스레드가 동기화 메소드를 수행 중이면 다른 스레드는 대기해야 한다. 스레드 사이의 통신 스레드 사이의 통신을 위해 wait(), notify(), notifyAll() 메소드가 사용되며, 이러한 메소드는 Object 클래스에 제공하고 있다. notify() 메소드는 대기 상태에 있는 스레드를 깨우는 역할을 한다.
10장. 다중 스레드 수고하셨습니다. 질문 있습니까?