자바

JAVA 자바 Thread 자바 스레드 : 작업 스레드 생성과 실행(1) - Thread 클래스로부터 직접 생성

알통몬_ 2017. 3. 15. 11:04
반응형


안녕하세요 알통몬입니다.

공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^

 


작업 스레드 생성과 실행

 멀티 스레드로 실행하는 애플리케이션을 개발하려면 

먼저 몇 개의 작업을 병렬로 실행할 지 결정하고 각  작업별로 스레드를 생성해야 합니다.

 

어떤 자바 애플리케이션이건 메인 스레드는 반드시 존재하기 때문에 

메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성하면 됩니다. 

자바에서는 작업 스레드도 객체로 생성되기 때문에 클래스가 필요합니다.

 java.lang.Thread 클래스를 직접 객체화해서 생성해도 되지만, 

Thread 를 상속해서 하위 클래스를 만들어서 생성할 수도 있습니다.


Thread 클래스로부터 직접 생성

 java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성하려면 아래와 같이 

Runnable을 매개값으로 갖는 생성자를 호출해야 합니다.

Thread thread = new Thread(Runnable target);


Runnable은 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라고 해서 붙여진 이름. 

Runnable은 인터페이스 타입이기 때문에 구현 객체를 만들어 대입해야 합니다. 

Runnable에는 run() 메서드 하나가 정의되어 있는데, 

구현 클래스는 run()을 재정의해서 작업 스레드가 실행할 코드를 작성해야 합니다. 

작성 방법)

Class task implements Runnable{

     public void run(){

        스레드가 실행할 코드;

      }

}


Runnable은 작업 내용을 가지고 있는 객체입니다. Runnable 구현 객체를 생성한 후, 

이것을 매개값으로 해서 Thread 생성자를 호출하면 비로소 작업 스레드가 생성됩니다.

Runnable task = new Task();         

  |                                      

  |_____________________             

                           |             

                           ▼            

Thread thread = new Thread(task);  


코드를 좀 더 절약하기 위해 Thrad 생성자를 호출할 때 Runnable 익명 객체를 매개값으로 사용할 수도 있습니다. 

위 방법보다는 이 방법이 더 많이 사용됩니다.

Thread thread = new Thread(new Runnable() {

       public void run(){

           스레드가 실행할 코드;

       }

});


Runnable 인터페이스는 run() 메서드 하나만 정의되어 있기 때문에 함수적 인터페이스입니다.

 따라서 아래처럼 람다식을 매개값으로 사용할 수도 있습니다. 가장 간단한 방법인데, 자바 8부터 지원됩니다.

람다식은 이후에 공부하겠습니다.

Thread thread = new Thread( () -> {

    스레드가 실행할 코드;

});


작업 스레드는 생성됨과 동싱에 실행되는 것이 아니라 start() 메서드를 아래와 같이 호출해야만 실행됩니다.

thread.start();

start()메서드가 호출되면 작업 스레드는 매개값으로 받은 Runnable의 run() 메서드를 실행하면서 

자신의 작업을 처리합니다.



0.5초를 주기로 비프음을 발생시키면서 동시에 출력하는 예제를 보겠습니다. 

비프음 발생과 출력작업은 서로 다른 작업이기 때문에 

메인 스레드가 두가지 작업을 동시에 할 수 없습니다. 

그렇기 때문에 아래 예제 처럼 작성하면 메인 스레드는 비프음을 다 발생시킨 후에 출력작업을 합니다.

import java.awt.Toolkit;


public class BeepPrintExample1 {

public static void main(String[] args) {

Toolkit toolkit = Toolkit.getDefaultToolkit();

for(int i=0; i<5; i++) {

toolkit.beep();

try { Thread.sleep(500); } catch(Exception e) {}

}



for(int i=0; i<5; i++) {

System.out.println("띵");

try { Thread.sleep(500); } catch(Exception e) {}

}

}

 

}


위 두가지 작업을 동시에 하려면 두 작업 중에 하나를 메인 스레드가 아닌 다른 스레드에서 실행해야 합니다

 출력 작업은 메인 스레드에서 하고 비프음을 다른 스레드에서 발생시키도록 수정해보겠습니다.

 우선 작업을 정의하는 Runnable 구현 클래스를 아래와 같이 작성합니다.

Runnable 구현 클래스)

import java.awt.Toolkit;


public class BeepTask implements Runnable {

public void run() {

Toolkit toolkit = Toolkit.getDefaultToolkit();

for(int i=0; i<5; i++) {

toolkit.beep();

try { Thread.sleep(500); } catch(Exception e) {}

}

}

}


실행 클래스)

import java.awt.Toolkit;


public class BeepPrintExample2 {

public static void main(String[] args) {

//how1

Runnable beepTask = new BeepTask(); // 비프 객체 생성

Thread thread = new Thread(beepTask);//작업 스레드 생성

//how2

/*Thread thread = new Thread(new Runnable() {

@Override

public void run() {

Toolkit toolkit = Toolkit.getDefaultToolkit();

for(int i=0; i<5; i++) {

toolkit.beep();

try { Thread.sleep(500); } catch(Exception e) {}

}

}

});*/

//how3

/*Thread thread = new Thread(() -> {

Toolkit toolkit = Toolkit.getDefaultToolkit();

for(int i=0; i<5; i++) {

toolkit.beep();

try { Thread.sleep(500); } catch(Exception e) {}

}

});*/ how1 부분에 대체하여 작업 스레드를 만들 수 있는 두 가지 방법입니다.

thread.start(); // 작업 스레드 호출

for(int i=0; i<5; i++) {

System.out.println("띵");

try { Thread.sleep(500); } catch(Exception e) {}

}

}

}


이 포스팅의 예제들은 비프음이 포함되어있기 때문에 각자 실행해보시면 되겠습니다.

반응형