목차
1. thread 구현하기
2. 스레드 동기화 문제
3. 스레드 상태제어
4. 스레드 함수 활용
5. 데몬스레드
1. thread 구현하기
구현하기 위해서는 스레드를 상속받거나 러너블 인터페이스를 구현하는 2가지방법이 있다.
자바에서 제공해주는 Thread 클래스를 상속하든지 Runnable 인터페이스를 implement 하든지 하면 된다. 그리고 그 다음은 둘 다 동일하게 run 함수를 오버라이딩하면 된다. 메인 함수에서의 사용법은 좀 다르다. (Runnable은 아래에서 설명) Thread 클래스를 상속받아서 구현한 경우에는 new 를 통해 인스턴스를 만든 후 start() 함수를 호출하면 만들어둔 thread 클래스의 run 함수가 동작한다. main 스레드와는 별개로 동작하며 스레드를 생성하는 데에 약간의 시간이 걸린다. 그래서 만약 run 함수가 문장하나를 출력하는 간단한 함수라 가정하고 다음의 코드를 통해 예시를 들면
MyThread t1 = new myThread();
t1.start();
System.out.println("hello");
메인 함수의 hello가 먼저 출력되고 그 다음에 run 함수에서 출력하는 문장이 콘솔에 찍힐 것이다.
[ 생성 예시 ]
public class MyThread extend Thread{
public void run() {
}
}
public class MyThread2 implements Runnable {
public void run() {
}
}
왜 굳이 두개로 나뉘어있는지 ????
-> 이렇게 두가지 방법을 제공하는 이유는 자바에서는 단일 상속밖에 불가능하기 때문이다. 이미 다른 클래스를 상속받은 클래스의 경우에는 Runnable을 implement하여 쓰레드를 구현할 수 있도록 지원해주는 것이다.
만약! Runnable로 구현했다면 해당 스레드 클래스를 사용하는 방법은 위와 다르다. Runnable에는 start 함수가 없으므로 아래와 같이 과정이 하나 더 추가된다. ( 번거롭게 느껴질 수 있음 ,,)
Thread 함수에서는 생성자로 Runnable 인스턴스도 인자로 받을 수 있게 되어있으므로 위와같이 Runnable로 구현한 스레드 클레스를 Thread 클래스의 생성자의 인자로 주어 Thread 인스턴스를 하나 만들면 된다.
스레드 동기화 문제
여러개의 스레드가 동일한 인스턴스를 멤버변수로 가지고 해당 객체의 여러 메소드들을 동시에 호출한다면 어떻게 될까? 여러 메소드가 동시에 실행될 경우 결과값이 올바르게 나오지 않는 경우가 있을 수도 있다. 이를 방지하기 위해서는 synchronized 키워드를 통해 모니터링 락을 걸어주면 된다.
함수에 synchronized를 걸었을 경우 어떻게 동작하는지 이해하기 위한 예제 코드는 다음과 같다.
결과는 이렇게 함수 하나가 전부 실행된 다음에야 다음 함수가 실행된다. 스레드의 start 함수가 호출되는 순서가 아닌 jvm내에서 순서가 결정되므로 실행할 때마다 순서가 달라질 수 있다. 여기서 만약 method3의 synchronized 키워드를 지운다면 어떻게 동작할까??
synchronized를 지운 3은 중간에 깔짝깔짝 등장하고 있다. 3은 다른 함수들이 실행되든 말든 실행되지만 1과 2는 동시에 실행이 되지 않고 1이 다 끝나고 나서야 2가 실행되는 것을 알 수 있다. 위에서 말했듯 jvm에 의해 실행 순서가 결정되므로 2가 먼저 실행되고 1이 실행될 수도 있는 것이다.
다시한번 얘기하지만 동일한 인스턴스일 경우에 한한다. 서로 다른 인스턴스들 간에는 synchronized 키워드가 동작하지 않는다.
스레드 상태 제어
스레드를 생성하고 start 함수를 호출한다면 스레드는 Runnable 상태와 Running 상태를 오가며 동작한다.
스레드의 sleep 함수나 Object의 wait 함수가 호출되면 Blocked 상태가 된다. sleep 함수는 특정시간이 지나면 알아서 빠져나와서 Runnable 상태나 Running 상태가 된다. wait 함수는 다른 스레드가 notify 함수를 호출해야 깨어날 수 있다. 스레드의 run함수가 종료되면 dead 상태가 된다. join 함수는 주로 메인 함수에서 활용하는데 해당 스레드가 종료될 때까지 기다리는 것이다.
스레드의 함수 활용(join wait notify)
wait과 join 둘 다 스레드가 종료될 때까지 기다리라는 함수이다.
여기서 join이 아니고 wait 함수를 썼다면 user1의 run 함수가 종료될 때까지 기다리는 것이 아니고 run 함수 내에서 notify() 함수가 호출될 때까지 기다리게 된다.
데몬 쓰레드 구현하기
여기서 데몬은 유닉스나 리눅스 계열 os의 데몬과 같다. 백그라운드에서 모든 스레드가 종료될 때까지 동작하는 스레드를 말한다. 사용방법은 간단하다.
스레드를 하나 만들어서 해당 스레드의 setDaemon 함수를 호출하여 인자를 true로 주면 된다.
thread.setDaemon(true);
thread.start();
지식 출처
해당 코스 강의를 정리한 글입니다.
'백엔드 > 자바' 카테고리의 다른 글
Ecplise failed while installing Java 1.8 해결 (0) | 2021.06.21 |
---|---|
스프링 mysql 연동 (0) | 2021.04.04 |
이클립스 사용 팁 (0) | 2021.01.29 |
자바의 date 클래스와 I/O 클래스 (0) | 2021.01.28 |
자바 set, list, map 사용법 기초 (0) | 2021.01.28 |