티스토리 뷰
Thread 클래스 상속과 Runnable 인터페이스 구현
- 스레드의 구현은 Thread 클래스를 상속받는 것과 Runnable 인터페이스를 구현하는 2가지 방법이 있습니다.
- Thread 클래스는 Runnable 인터페이스를 구현한 것이기 때문에 어느 것을 사용해도 상관은 없지만, Runnable 인터페이스를 구현하면 원하는 기능을 추가할 수 있습니다.
이것은 장점이 될 수도 있지만, 해당 클래스를 수행할 때 별도의 스레드 객체를 생성해야 한다는 단점이 있을 수 있습니다. 또한 자바는 다중 상속을 허락하지 않습니다.
따라서 스레드를 사용할 때 이미 상속받은 클래스가 있다면 Runnable 인터페이스를 구현해야 합니다. - Runnable 인터페이스를 구현한 클래스
public class RunnableImpl implements Runnable {
public void run() {
System.out.println("This is RunnableImpl.");
}
}
- Thread 클래스를 상속받아 구현한 클래스
public class ThreadExtends extends Thread {
public void run() {
System.out.println("This is ThreadExtends.");
}
}
이 클래스들을 어떻게 실행해야 할까 ?
-
Thread 클래스를 상속받은 경우에는 start() 메소드를 호출하면 실행
-
Runnable 인터페이스를 구현한 경우에는 Thread 클래스의 Runnable 인터페이스를 매개변수로 받는 생성자를 사용해
Thread 클래스를 만든후 start() 메소드를 호출해야 합니다. -
실행 소스 코드
public class RunThreads {
public static void main(String[] args) {
RunnableImpl runnableImpl = new RunnableImpl();
ThreadExtends threadExtends = new ThreadExtends();
new Thread(runnableImpl).start();
threadExtends.start();
}
}
sleep(), wait(), join() 메소드
현재 진행 중인 스레드를 대기하도록 하기 위해서 위 3가지 메소드를 사용하는 방법이 있습니다.
- 위 3가지 메소드는 모두 예외를 던지도록 되어 있어 사용할 때는 반드시 예외 처리를 해줘야 합니다.
wait() 메소드
- 모든 클래스의 부모 클래스인 Object 클래스에 선언되어 있으므로 어떤 클래스에서든 사용할 수 있습니다.
- sleep()과 마찬가지로 명시된 시간만큼 해당 스레드를 대기시킵니다. sleep()과 다른 점은 매개변수인데, 만약 아무런 매개변수를 지정하지 않았다면
notify() 또는 notifyAll() 메소드가 호출될 때까지 대기합니다.
sleep() 메소드
- 명시된 시간만큼 해당 스레드를 대기시킵니다.
- sleep(long millis) : 명시된 ms만큼 해당 스레드가 대기합니다. static 메소드이기 때문에 스레드 객체를 통하지 않아도 사용할 수 있습니다.
- sleep(long millis, int nanos) : 명시된 ms + 명시된 나노 시간만큼 해당 스레드가 대기합니다. 여기서 나노 시간은 0~999999까지 사용할 수 있습니다. (이것도 마찬가지로 static)
join() 메소드
- 명시된 시간만큼 해당 스레드가 죽기를 기다립니다.
- 아무런 매개변수를 지정하지 않으면 죽을 때까지 계속 대기합니다.
interrupt(), notify(), notifyAll() 메소드
- isAlive()라는 메소드도 있는데, 이것은 해당 스레드가 살아있는지 확인하는 메소드입니다.
- 스레드가 살아있다면 true, 아니라면 false를 리턴합니다.
interrupt() 메소드
- 앞서 명시한 sleep(), wait(), join() 메소드를 모두 멈출 수 있는 유일한 메소드는 interrupt() 메소드입니다.
- 하지만 interrupt() 메소드가 절대적인 것은 아닙니다.
- 간단하게 설명하자면, interrupt() 메소드는 해당 스레드가 block되거나 특정 상태에서만 작동합니다.
- interrupt() 메소드가 호출되면 중지된 스레드는 InterruptedException이 발생합니다.
- 제대로 수행되었는지 확인하려면 interrupted() 메소드를 호출하거나 isInterrupted() 메소드를 호출하면 됩니다.
- interrupted() 메소드는 스레드의 상태를 변경시킵니다.
- isInterrupted() 메소드는 단지 스레드의 상태만을 리턴합니다.
notify(), notifyAll() 메소드
-
위 두 메소드 모두 wait() 메소드를 멈추기 위한 메소드입니다.
-
위 두 메소드는 Object 클래스에 정의되어 있는데, wait() 메소드가 호출된 후 대기 상태로 바뀐 스레드를 깨웁니다.
- notify() 메소드는 객체의 모니터와 관련 있는 단일 스레드를 깨웁니다.
- notifyAll() 메소드는 객체의 모니터와 관련 있는 모든 스레드를 깨웁니다.
-
대기 메소드와 중단 메소드의 사용법
public class Sleep extends Thread {
public void run() {
try {
Thread.sleep(10000); // 10초간 대기한 후 종료합니다.
} catch (InterruptedException e) {
System.out.println("Somebody stopped me.");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
Sleep sleep = new Sleep();
sleep.start(); // 스레드를 시작합니다.
try {
int count = 0;
while (count < 5) {
sleep.join(1000); // 1초씩 기다립니다.
count++;
System.out.format("%d second waited\n", count);
}
if (sleep.isAlive()) { // 스레드가 살아있는지 확인합니다.
sleep.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
'Language > Java' 카테고리의 다른 글
Reflection class (0) | 2018.06.01 |
---|---|
Synchronized (0) | 2018.06.01 |
Process & Thread (0) | 2018.06.01 |
IO (0) | 2018.06.01 |
Static (0) | 2018.06.01 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- class
- cross
- https
- Spring Boot
- stateful
- Cross Origin
- Token
- cors
- NoSQL
- ehcache
- output
- URI
- redis
- stateless
- ngrinder
- Java
- HTTP
- thread
- Runnable
- script
- iinput
- Groovy
- web
- SPOF
- MongoDB
- auth
- synchronized
- 404
- 대규모
- JWT
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함