19.04.16 멀티 스레드

Back-End/Java 2019. 4. 16. 13:48
728x90
반응형



-멀티 스레드-


애플리케이션 내부의 멀티 태스킹 즉 프로세스 내부에서 두 가지 작업을 동시에 실행하는것.
멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를
발생시키면 프로세스 자체가 종료될 수 있어 다른 스레드에게 영향을 미치게 된다.




-스레드의 구현과 실행-


1. Thread 클래스 상속
2. Runable 인터페이스 구현




-멀티 스레드 장,단점-


장점


-자원을 보다 효율적으로 사용할 수 있음
-작업이 분리되어 코드가 간결해 짐



단점


-교착상태가 발생하지 않도록 주의해야 한다.



- 예제 및 출력 결과 -


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
package com.hs.chap12;
 
public class BeepPrintExample extends Thread {
 
    // 생성자 정의
    public BeepPrintExample(String name) {
        super(name);
    }
 
    // 현재 실행중인 스레드의 이름을 출력한다.
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
 
    public static void main(String[] args) {
        BeepPrintExample a0 = new BeepPrintExample("스레드 1");
        BeepPrintExample a1 = new BeepPrintExample("스레드 2");
        BeepPrintExample a2 = new BeepPrintExample("스레드 3");
 
        a1.setName("스레드 50");
 
        a0.start();
        a1.start();
        a2.start();
    }
}
 
cs



 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.hs.chap12;
 
public class MyThread extends Thread {
    //생성자 추가
    public MyThread (String name) 
    {
        super(name); 
    }
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            //현재 실행중인 스레드의 이름
            System.out.println(Thread.currentThread().getName());
        }
        try {
            Thread.sleep(1500); //실행을 멈추는 거기때문에 예외처리가 반드시 필요
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
package com.hs.chap12;
 
public class ExternThread {
    public static void main(String[] args) {
        MyThread t1 = new MyThread("스레드1");
        MyThread t2 = new MyThread("스레드2");
 
        t1.start();
        t2.start();
 
    }
}
 
cs


-스레드의 이름-

 

Thread 클래스의 setName()메소드로 스레드의 이름을 변경
Thread 클래스의 getName()메소드로 스레드의 이름을 알수 있다.

 


 

-스레드 우선순위-

 

동시성: 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질

병렬성: 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질

스레드 스케줄링 : 스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해
   동시에 실행할 것인가를 결정

   (짧은 시간에 번갈아가면서 run() 메소드를 조금씩 실행함)

 


 

-동기화 메소드 및 동기화 블록-

임계 영역 = 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역, 임계 영역을
            지정하기 위해 동기화 메소드와 동기화 블록을 제공한다.
            형식 : 메소드선언에 synchronized 키워드를 붙이면 된다.


 


-스레드 상태-

 

실행 대기 상태 : 스케줄링이 되지 않아서 실행을 기다리고 있는 상태
실행 상태 : 실행 대기 상태에 있는 스레드 중에서 선택된 스레드가 run() 메소드를 실행한 상태

실행 종료 상태 : 실행 상태에서 run() 메소드가 종료되면 스레드의 실행이 멈추게 되는 상태



 

-스레드 상태 확인-

 

getState() 메소드는 스레드 상태에 따라서 Thread.State 열거 상수를 리턴한다.


 


-Thread 클래스 메소드-


sleep() : 주어진 시간동안 일시 정지
yield() : 다른 스레드에게 실행 양보
join() : 다른 스레드의 종료를 기다림

notify() : 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만듬



-데몬 스레드-

 

주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다.
주의할 점은 start() 메소드가 호출되고 나서 setDaemon(true)를 호출하면 예외가 발생하기 때문에
start() 메소드 호출 전에 setDaemon(true)를 호출해야 한다.

 

-스레드 그룹-

 

관련된 스레드를 묶어서 관리하는 것
스레드 그룹을 생성하는 방법은 다음 생성자 중 하나를 이용해서 스레드그룹 객체를 만들면 된다.

ThreadGroup tg = new ThreadGroup(String name);
ThreadGroup tg = new ThreadGroup(ThreadGroup parent, String name);

-예제 및 출력 결과-

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package synchronization;
 
public class WorkThread extends Thread {
    public WorkThread(ThreadGroup threadGroup, String threadName) {
        super(threadGroup, threadName);
    }
 
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println(getName() + "interrupted");
                break;
            }
        }
        System.out.println(getName() + "종료됨");
    }
}
 
cs


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
package synchronization;
 
public class ThreadGroupExample {
 
    public static void main(String[] args) {
        ThreadGroup myGroup = new ThreadGroup("myGroup");
        WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
        WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
 
        workThreadA.start();
        workThreadB.start();
 
        System.out.println("[main 스레드 그룹의 list()메소드 출력 내용]");
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        mainGroup.list();
        System.out.println();
 
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
 
        System.out.println("[myGroup 스레드 그룹의 interrupt()메소드 호출]");
        myGroup.interrupt();
    }
}
 
cs



 

 

 

-스레드풀-

 

작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가
맡아 처리한다.

java.util.concurrent 패키지에서 ExecutorService 인터페이스와 ExecutorService 구현 객체를 만들 수 있는데, 이것이 바로 스레드풀이다.

 

 


-작업 생성-

 

하나의 작업은 Runnable 또는 Callable 구현 클래스로 표현한다.
Runnable과 Callable의 차이점은 작업 처리 완료 후 리턴값의 유무이다.
Runnable의 run() 메소드는 리턴값이 없고, Callable의 call() 메소드는 리턴값이 있다.

 

 

 

-작업 처리 요청-

 

ExecutorService의 작업 큐에 Runnable 또는 Callable 객체를 넣는 행위를 말한다.






-중요 예제-


728x90
반응형
: