전편의 Runnable Interface를 이용한 Thread를 구현의 뒷편입니다.
제가 실습한 코드는 혹시 몰라 올려둡니다. https://github.com/helloJosh/nhn-homework-thread-study
public class RunnableThreadCounter implements Runnable{
String name;
int count;
int maxCount;
public RunnableThreadCounter(String name, int maxCount){
// 중략
}
// Gett 중략
@Override
public void run(){
while(count < maxCount){
try{
Thread.sleep(1000);
count++;
System.out.println(name +":"+count);
} catch (InterruptedException e) {
System.out.println(name+": interrupted");
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
RunnableCounter counter = new RunnableCounter("counter", 5);
Thread thread = new Thread(counter);
thread.start();
}
}
public class RunnableThreadCounter implements Runnable{
String name;
int count;
int maxCount;
Thread thread;
public RunnableThreadCounter(String name, int maxCount){
this.name = name;
this.maxCount = maxCount;
count =0;
thread = new Thread(this);
}
public void start(){
thread.start();
}
public void stop(){
//thread.currentThread().interrupt();
thread.interrupt();
}
public Thread getThread(){
return this.thread;
}
// Getter 중략
@Override
public void run(){
while(!Thread.currentThread().isInterrupted() && count < maxCount){
try{
Thread.sleep(1000);
count++;
System.out.println(name +":"+count);
} catch (InterruptedException e) {
System.out.println(name+": interrupted");
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
RunnableThreadCounter[] counters = new RunnableThreadCounter[10];
Thread[] threads = new Thread[10];
LocalTime now = LocalTime.now();
boolean allStopped = false;
for(int i=0; i<counters.length ; i++){
counters[i] = new RunnableThreadCounter("counter "+(i+1), 10);
counters[i].getThread().start();
}
while(!allStopped){
if((counters[0].getCount()>5)){
for(int i=0;i<counters.length;i++){
counters[i].getThread().interrupt();
}
}
allStopped = true;
for(int i=0;i<counters.length;i++){
if(counters[i].getThread().isAlive()){
allStopped = false;
}
}
}
System.out.println("end :" + now);
}
}
참고1
Thread.interrupt()
,Thread.currentThread().interrupt()
는 완전히 다른 코드이다.
Thread
는 필드에 저장된 Thread를 의미하고Thread.currentThread
는 현재 돌고 있는 Thread를 의미한다. 즉CurrentThread()
함수를 사용하면 Main Thread까지 튀어나오니 조심해야한다.
참고2
Thread 프로그래밍할때는 디버깅 모드가 제대로 작동하지 않아 Log나 콘솔에 직접 찍어줘야한다. 디버깅 모드로 실행시 원래 결과값과 다른 값이 나온다.
코드와는 다르게 생각해야하는 것 같다.
ExecutorService를 이용해 thread pool을 생성한다. 이때, pool의 크기는 1로 한다.
ExecutorService pool = Executors.newFixedThreadPool(1);
Thread pool에 RunnableCounter instance를 생성해 넘기고 실행하도록 한다.
pool.execute(new RunnableCounter("counter1", 5));
pool.execute(new RunnableCounter("counter2", 5));
Thread pool을 종료하도록 명령을 내리고, 종료되길 기다린다.
pool.shutdown();
System.out.println("Shutdown called");
while (!pool.awaitTermination(2, TimeUnit.SECONDS)) {
System.out.println("Not yet finished");
}
System.out.println("All service finished");
Class 확장 | Interface 구현 |
---|---|
multiple inheritance을 지원하지 않으므로, 다른 class로부터의 추가적인 확장이 불가능하다. | Interface에 대한 multiple inheritance가 지원되고, 구현된 후에도 해당 class의 확장이 가능하다 |
Instance 생성 후 바로 실행할 수 있다. | Instance 생성 후 바로 사용할 수 없고, 추가적인 Thread object가 요구된다. |
간단한 class라도 별도의 class 정의가 필요하다. | Runnable interface는 functional interface로 Lambda로 구현 가능하다. |