ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스레드 Thread
    language/JAVA 2019. 1. 30. 17:36
    반응형

    때로는 애플리케이션이 한 번에 두가지 이상의 일을 처리해야 할 때가 있습니다. 자바에서는 언어 자체에 다중 스레딩 기능이 내장되어 있습니다.


    멀티 스레드를 이용하게 되면 한 번에 두 가지 이상의 일을 처리할 수 있게 됩니다. 다른 작업이 끝날 때 까지 기다릴 필요가 없기 때문에 응답시간을 개선 시키고 유휴자원 발생을 줄임으로서 경제성을 높일 수 있습니다.


    하지만 교착상태가 발생할 수 있고 스레드 스케줄에 따라 오히려 실행시간이 지연되는 경우도 있을 수 있습니다.


    여러개의 스레드가 있다는 것은 스택이 여러 개 있다는 것입니다. 그림에서처럼 메인스레드에서 호출된 각각의 다른 스레드들이 있고 그 스레드 들 마다 각각 스택을 가지고 있습니다. 멀티 스레드 라는 것은 이런 식으로 여러개의 호출 스택을 만드는 것과 같습니다. 이렇게 호출 스택이 여러 개 있으면 여러 개의 작업이 동시에 일어나는 것 처럼 보이게 할 수 있습니다.


    실제로 두 개 이상의 작업이 동시에 일어나기 위해서는 두 개 이상의 CPU가 필요합니다. 싱글코어 환경에서는 멀티스레드를 사용한다고 해서 실제로 동시에 작업이 일어나는 것은 아닙니다. 그냥 동시에 작업이 일어나는 것 처럼 보일 뿐입니다. 즉, 여러 스택이 아주 빠르게 번갈아 실행되기 때문에 여러 스택이 동시에 실행되는 것 처럼 보이는 것입니다. (Yes, the Java multiple threads can be running in multiple cores but I don't think it is quite possible to make it run in x number of cores.)


    자바에서 스레드를 생성하기 위해서는  java.lang.Thread 클래스의 인스턴스를 만들어 줘야 합니다.


    클래스에서 Thread 클래스를 상속받거나 Runnable 인터페이스를 구현하면 Thread 클래스의 인스턴스가 될 수 있습니다.


    하지만 하위 클래스가 상위 클래스를 구체화 한다라는 객체지향적인 관점에서 보면 Thread 클래스를 상속받는 것 보다 Runnable 인터페이스를 구현하는 것이 더 올바르다고 할 수 있습니다.


    또 Thread 클래스를 확장한 클래스는 다른 클래스를 상속받을 수 없다는 단점이 있습니다.


    실제로 Runnable interface를 구현해서 새로운 Thread를 만들어 보겠습니다.


    Runnable 인터페이스에서 구현해야 할 메소드는 run() 메소드 뿐입니다. run() 메소드에서 실행되는 작업들이 스레드가 실제로 하는 작업이 됩니다.


    그리고 메인 메소드에서 Runnable 객체를 만듭니다.


    그 다음에 새로운 Runnable 객체를 Thread 생성자에 전달합니다. 이렇게 하면 새로운 thread객체에서 새로운 스택 맨 밑에 들어갈 메소드(즉, 처음 실행 할 메소드)인 run() 을 알려주게 됩니다.


    그리고 Thread 객체의 start() 메소드를 호출합니다. 바로 이 순간 Thread 인스턴스에서 새로운 실행 스레드를 만들어 내고 Runnable 객체에서 구현한 run() 메소드를 스택의 바닥에 집어넣습니다.(실행)


    앞서서 스레드는 여러 스택을 빠르게 번갈아가면서 실행한다는 이야기를 했습니다. 그러나 스레드의 실행 순서는 개발자가 마음대로 제어할 수 없습니다. 각 스레드의 실행 순서는 모두 스레드 스케줄러가 내립니다.


    주의해야 할 것은 스케줄러가 어떤 특별한 방식으로 작동할 것을 가정하고 프로그램을 만들면 안된다는 것입니다. 스케줄러는 시스템이나 JVM에 따라 다르게 작동할 수 있고 같은 시스템에서도 결과가 달라질 수 있습니다.


    가장 좋은 것은 완전히 비동기적인 방법으로 작동해도 아무런 문제가 없는 경우에만 멀티 스레드를 사용하는 것입니다. 하지만 꼭 스레드의 실행 순서에 영향을 줘야 할 때 사용할 수 있는 것이 sleep() 메소드 입니다.


    이 메소드를 호출하면 해당 스레드를 대기 상태로 만들 수 있습니다. 이 때 대기 시간을 밀리초 단위로 지정할 수 있습니다. 물론 대기상태가 지나가고 나면 다시 스케줄러가 그 스레드를 실행시킬 수 있게 됩니다.


    이런 방법을 통해 특정 스레드의 실행 순서를 뒤로 늦출 수 있습니다.

    반응형

    'language > JAVA' 카테고리의 다른 글

    제네릭, Generic  (0) 2019.01.30
    동기화 synchronized  (0) 2019.01.30
    네트워크, 소켓  (0) 2019.01.30
    serialization(직렬화)  (0) 2019.01.23
    GUI / innerclass(내부클래스)  (0) 2019.01.23
Designed by Tistory.