프로그래밍/JAVA2009. 12. 4. 11:15
쓰레드(Thread)란, 프로그램의 실행 흐름으로서, 일반적으로 프로그램이 시작되며 main 메소드가 호출되고 하나의 메인 쓰레드를 지니게 됩니다. 프로그램에 따로 쓰레드를 생성하여 관리하는 코드가 없다면 프로그램은 시작부터 끝가지 단 하나의 쓰레드를 지니게되며 이런 프로그램을 싱글쓰레드 프로그램이라 합니다.

요즘 대부분의 CPU들은 다중코어 아키텍처를 택하고 있기때문에, CPU의 능력을 최대한 활용하기 위해서는 싱글쓰레드로 프로그램보다는 다수의 쓰레드를 두어 병렬처리가 가능하도록 설계된 멀티쓰레드 프로그램이 좋습니다.

1. Thread 클래스
Java에서 쓰레드를 생성하기 위해서 Thread 클래스를 상속하여 이용하거나, Runnable 인터페이스를 구현하여 Thread 객체를 생성할수 있습니다. 2가지 방법 모두 쓰레드를 사용하는데 문제는 없으나 Thread 클래스를 직접 상속하여 run 메소드를 오버라이드 하는 방법보다는 Runnable 인터페이스를 이용하는 방법을 추천합니다.(Java에서는 다중 상속이 불가능 하기때문에 Thread를 상속하는 방법은 다른 클래스를 상속받을수 없음을 의미합니다.)
class MyThread extends Thread {  
	@Override
	public void run() {
		// TODO here
	}
}

public class ThreadTest {
	public static void main(String[] args) {
		MyThread t = new MyThread();
		t.start();
		t.join();
	}
}
public class ThreadTest {
	public static void main(String[] args) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
			        // TODO here	
			}
		});
		t.start();
		t.join();
	}
}

2. 쓰레드 종료
쓰레드는 run메소드가 종료할때까지 유지되는데, 일반적으로 많은 워커쓰레드는 내부에 무한루프를 지니며, 외부의 입력조건에 따라 쓰레드를 종료시키는 구조를 지니고 있습니다. 자바에서 스레드를 종료할 때는 상태변수(state variable)를 사용해 run() 메소드를 탈출하는 방식을 사용하는데, 이 것을 "state based" singnaling이라 합니다. 기존에 제공되던 Thread.stop(), Thread.suspend(), Thread.resume()은 더 이상 사용할 수 없습니다.
class MyThread extends Thread {  
	
	private volatile boolean isRun = true;
	
	public void setRun(boolean isRun) {
		this.isRun = isRun;
	}

	@Override
	public void run() {
		while( isRun ) {
			// TODO here	
		}
	}
}

public class ThreadTest {
	public static void main(String[] args) {
		MyThread t = new MyThread();
		// TODO here
		t.setRun(false);
	}
}
class MyThread extends Thread {  
	@Override
	public void run() {
		try {
			while( true ) {
				// TODO here
			}
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			return;
		}
	}
}

public class ThreadTest {
	public static void main(String[] args) {
		MyThread t = new MyThread();
		// TODO here
		t.interrupt();
	}
}
첫번째 방법은 직접 상태변수를 선언하고 그 것을 이용하는 것입니다. 자기 쓰레드의 종료 상태를 지정할 수 있는 상태변수(r/w enabled)를 변수로  정의하고, run() 메소드 내에서 주기적으로 종료 상태를 검사해서 메소드를 탈출(리턴)합니다. 상태변수는 volatile로 선언되거나 또는, 동기화된(synchronized) 방법으로 접근되어야 함에 주의해야합니다.

두번째 방법은 Thread.interrupt()를 이용하는 것입니다. VM 내부적으로 intrrupt status라는 내부변수를 사용하며, 위의 방법으로 다룰 수 없는 상태의 스레드를 종료하는 데 사용할 수 있습니다. 즉, wait(), wait(long), wait(long, int), 또는 join(), join(long), join(long, int), static sleep(long), static sleep(long, int) 등으로 블럭된(blocked state) 스레드의 경우에 해당 스레드 객체를 통해서 Thread.interrupt()를 호출하는 즉시, 블럭해제됨과 동시에 InterruptedException을 발생시킨후 interrupt status는 초기화(clear)됩니다.. 따라서 try 구문의 catch 블럭 내에서 적당한 종료 코드를 작성하여 쓰레드를 종료할 수 있으며, run() 메소드 외부에서 InterruptedException을 캐치한 경우에는, InterruptException을 rethrow 하거나, Thread.currentThread().interrupt()를 reassert함으로써 run()메소드까지 interrupt status가 전달되도록 해야 할수 있습니다. intrrupt status의 상태는 static Thread.interrupted()를 통해서 검사할 수 있습니다.

'프로그래밍 > JAVA' 카테고리의 다른 글

MSSQL with JDBC  (0) 2010.02.03
JavaMail 첨부파일 읽기  (0) 2010.01.28
JavaMail with IMAP  (0) 2010.01.27
JavaMail을 이용하며 메일전송  (0) 2010.01.15
RSA 암호화  (0) 2010.01.15
Java 쓰레드  (0) 2009.12.04
스트러츠 properties 한글 편집  (0) 2009.12.03
Java XML Parser JDOM  (2) 2009.09.03
JRE Detection  (0) 2009.08.11
자바 웹 스타트(Java Web Start)  (0) 2009.08.07
JFreeChart with SWT  (0) 2009.07.14
Posted by devop

댓글을 달아 주세요