JAVA

쓰레드

CodePoetry 2014. 10. 14. 10:31
  • Thread를 상속받은 클래스에서는 반드시 run() method를 구현해주어야 한다. 이 메소드를 start() method를 통해 시작된다.

  • run() method가 할 일을 충분히 했다고 판단되면 yield() 를 호출하여 다른 쓰레드가 CPU를 사용해도 된다고 명시적으로 알려줄 수도 있다. 만약 오래 걸리는 작업이 진행중이라면 yield()가 호출되기 전이라도 다른 쓰레드의 run()이 호출될 수 있다.

  • 쓰레드에 우선순위를 설정할 수 있다. setPriority(int priority)형태로 설정가능하다. 우선순위 상수로는 Thread.MIINPRIORITY, Thread.MAXPRIORITY 등이 있다. Daemon Thread는 프로그램의 핵심요소는 아니지만 프로그램이 실행되는 동안 백그라운드로 일반 서비스를 제공하는 것을 말한다.

  • Daemon 쓰레드가 종료되지 않았더라도 프로그램은 종료될 수 있다. (Daemon의 출력결과가 없을 수도 있음) setDaemon(true)를 호출해 daemon 쓰레드임을 지정할 수 있으며, 반드시 start()이전에 호출해주어야 한다.

  • 쓰레드가 Daemon thread인지 알아보려면 isDaemon() 쓰레드 A가 쓰레드 B에 대해 B.join()을 호출하면 A는 B가 종료될 때까지 기다린다.

  • 다른 클래스를 상속받아야 한다면 다중 상속이 불가능한 JAVA의 특성상 Runnable Interface를 구현한다.

    Runnable interface는 run() 메소드만 구현하도록 정의하고 있으며 Thread class 또한 Runnable을 구현하였다.

  • 만약 Thread 객체의 메소드(eg. toString() or getName())가 필요하다면 명시적으로 Runnable을 이용한 Thread 객체를 생성해주어야 한다. 이 특별한 Thread 생성자는 아래와 같다
    java.lang.Thread.Thread(Runnable target, String name)

  • 반드시 Runnable 인터페이스를 사용해야 하는 경우가 아니라면 Thread 클래스를 이용하는 것이 편리하다.

  • 메소드 내부에서 스레드를 생성하는 것이 좋다. 여러 다른 작업 사이에 스레드 시작 시점을 정할 수 있기 때문이다.

    class ThreadMethod { // 스레드 코드를 실행하는 분리된 메소드 : runThread()
        private int countDown = 5;
        private Thread t;
        private String name;
        public ThreadMethod(String name) {
            this.name = name;
        }
        public void runThread() {
            if (t == null) {
                t = new Thread(name) {
                    public void run() {
                        while(true) {
                            System.out.println(this);
                            if (--countDown == 0) return;
    
                            try {
                                Thread.sleep(10);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                    public String toString() {
                        return getName() + ": " + countDown;
                    }
                };
            }
            t.start();
        }
    }