쓰레드란?
스레드란 실행 단위다. main() 메소드를 만들면 main() 메소드룰 실행하는 하나의 스레드가 생긴다.
스레드를 사용하게 되면 보다 빠른 처리가 가능하다. 하나의 응용프로그램을 여러 개의 스레드로 구성하면 스레드 사이의 문맥 교환 시 작업량이 작고 시간이 짧은 장점을 가진다.
인터넷 브라우저로 예를 들면 멀티 스레딩을 통해 검색을 하며 인쇄도 할 수 있고, 인터넷으로 영화도 볼 수 있다. 만약 인터넷 브라우저가 싱글 스레드로 구성되어 있다면 검색을 하는중에는 영화는 볼 수 없으며 인쇄도 할 수 없다.
Thread의 상태
- NEW : 스레드가 객체가 생성됨, 아직 실행되지 않은 상태
- RUNNABLE : 스레드가 실행되기 위한 준비단계
- WAITING : 다른 스레드가 통지할 때까지 기다리는 상태
- TIMED_WAITING : 주어진 시간 동안 기다리는 상태
- BLOCKED : 객체 잠금이 풀릴 때까지 기다리는 상태
- TERMINATED : 실행을 마친 상태
Thread Class
클래스 경로명 java.lang.Thread
Thread 메소드 |
내용 |
Thread() |
단순한 스레드 객체 생성 |
Thread(Runnable target) |
Runnable 객체인 target을 이용하여 스레드 객체 생성 |
Thread(String name) |
이름이 name인 스레드 객체 생성 |
Thread(Runnable target,String name) |
Runnable 객체를 이용하며, 이름이 name인 스레드 객체 생성 |
void run() |
스레드 코드로서 JVM에 의해 호출된다. 반드시 오버라이딩하여 스레드 코드를 작성하여야 한다. 이 메소드가 종료하면 스레드도 종료 |
void start() |
JVM에게 스레드를 실행을 시작하도록 요청(run() 메소드 호출) |
Void interrupt() |
스레드 강제 종료 |
Static void yield() |
다른 스레드에게 실행을 양보 |
void join() |
스레드가 종료될 때까지 기다린다. |
long getId() |
스레드의 ID값 리턴 |
String getName() |
스레드의 이름 리턴 |
int getPriority() |
스레드의 우선순위 값 리터 |
void setPriority(int n) |
스레드의 우선순위 값을 n으로 변경 |
Thread.State getState() |
스레드의 상태 값 리턴 |
static void sleap(long m) |
m밀리초만큼 sleep |
static Thread currentThread() |
현재 실행 중인 스레드 객체의 래퍼런스 리턴 |
boolean isAlive() |
스레드가 실행중이면 True 끝났으면 False 리턴 |
void suspend() |
스레드 일시정지 |
void resume() |
일시 정지된 스레드 다시 실행 |
Thread 예제
import java.lang.Thread;
class Sum{
int num=0;
int sum(){
for(int i=0;i<1000;i++) {
num+=1;
}
return num;
}
}
class ThreadEX extends Thread{
Sum s = new Sum();
public void run() {
String threadName = Thread.currentThread().getName(); //쓰레드 이름 받아오기
System.out.println(threadName+" : "+s.sum());
}
}
public class Main {
public static void main(String[] args) {
ThreadEX t = new ThreadEX();
Thread ex1 = new Thread(t,"a"); //첫번째 쓰레드 객체 생성 쓰레드 이름은 a
Thread ex2 = new Thread(t,"b"); //두번째 쓰레드 객체 생성 쓰레드 이름은 b
//멀티 쓰레드 시작
ex1.start();
ex2.start();
}
}
실행 결과
-
위와 같이 상속을 받아서 쓰레드를 사용할 수도 있지만, 상속은 한개 밖에 받을 수 없기에 Runnable 인터페이스를 주로 사용한다. Runnable은 추상 메소드 run()만 가지고 있다.
Runnable 사용 예제
import java.lang.Thread;
class Sum{
int num=0;
int sum(){
for(int i=0;i<1000;i++) {
num+=1;
}
return num;
}
}
class ThreadEX implements Runnable{
Sum s = new Sum();
public void run() {
String threadName = Thread.currentThread().getName(); //쓰레드 이름 받아오기
System.out.println(threadName+" : "+s.sum());
}
}
public class Main {
public static void main(String[] args) {
Runnable r = new ThreadEX();
Thread ex1 = new Thread(r,"a"); //첫번째 쓰레드 객체 생성 쓰레드 이름은 a
Thread ex2 = new Thread(r,"b"); //두번째 쓰레드 객체 생성 쓰레드 이름은 b
//위에서는 쓰레드의 이름을 설정해 주었지만 설정하지 않을 경우 Thread(r); 로 사용하면 된다.
//멀티 쓰레드 시작
ex1.start();
ex2.start();
}
}
실행 결과
위의 예제들을 보면 실행결과가 예상햇던 것과는 다르게 나왔을 것이다. 그 이유는 스레드를 동기화해주지 않았기 때문이다.
동기화를 안해주게 되면 쓰레드 ex1이 Sum클래스의 num에 접근 했을 때 동시에 ex2도 접근하는 일이 생기기 때문이다. 그렇기 때문에 예상했던 2000과는 다른 결과가 나오게 된것이다.
멀티 쓰레드 동기화에 관해서는 다음 글에서 설명하겠다.
https://ming9mon.tistory.com/44
'프로그래밍 > 자바' 카테고리의 다른 글
자바 숫자야구 소스 (0) | 2019.03.07 |
---|---|
자바 멀티 쓰레드(Thread) 동기화 예제 (0) | 2019.03.05 |
자바 파일 입출력 과 입출력 스트림 (0) | 2019.02.27 |
자바 Jsoup를 이용한 웹 크롤링 예제 (3) | 2019.02.25 |
자바 제네릭(generic) (0) | 2019.02.23 |