chapter12. 멀티스레드 


12.1 멀티 스레드 개념


* 프로세스(process)

// 실행 중인 하나의 프로그램을 말한다

// 하나의 프로그램은 다중 프로세스를 만들기도 한다.


* 멀티 태스킹(multi taking)

- 두 가지 이상의 작업을 동시에 처리하는 것


- 멀티 프로세스 : 독립적으로 프로그램들을 실행하고 여러가지 작업 처리

// 하나의 프로세스에서 오류가 발생해도 다른 프로세스에게 영향을 미치지 않는다


- 멀티 스레드 : 한 개의 프로그램을 실행하고 내부적으로 여러가지 작업 처리

// 하나의 프로세스 내부에 생성되기 때문에 

하나의 스레드가 예외를 발생 시키면 프로세스 자체가 종료될 수 있어서 다른 스레드에게 영향을 미치게 된다.


- 멀티 프로세스가 애플리케이션 단위의 멀티 태스킹이라면

멀티 스레드는 애플리케이션 내부에서의 멀티 태스킹이라고 볼 수 있다.



12.1.2 메인 스레드

- 모든 자바 프로그램은 메인 스레드가 main() 메소드를 실행하면서 시작된다.

- main() 메소드의 첫 코드부터 아래로 순차적으로 실행된다.

- main() 메소드의 마지막 코드를 실행하거나, return 문을 만나면 실행이 종료된다.



- main 스레드는 작업 스레드들을 만들어서 병렬로 코드들을 실행할 수 있다.

즉, 멀티 스레드를 생성해서 멀티 태스킹을 수행한다.



- 프로세스의 종료

// 싱글 스레드 : 메인 스레드가 종료되면 프로세스도 종료된다.

// 멀티 스레드 : 실행 중인 스레드가 하나라도 있다면, 프로세스는 종료되지 않는다

(메인 스레드가 작업 스레드보다 먼저 종료되더라도, 작업 스레드가 계속 실행 중이라면 프로세스는 종료되지 않는다)


12.2 작업 스레드 생성과 실행



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

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


// 1. java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성하려면 다음과 같이 Runnable을 매개값으로 갖는 생성자를 호출해야한다


1
Thread thread = new Thread(Runnable target);
cs

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


12.2.1 Thread 클래스로부터 직접 생성



메인 스레드만 이용한 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package sec02.exam01_createthread;
 
import java.awt.Toolkit;
 
public class BeepPrintExample1 {
    public static void main(String[] args) {
        Toolkit toolkit = Toolkit.getDefaultToolkit(); // Toolkit 객체 얻기    
        for(int i=0; i<5; i++) {        
            toolkit.beep(); // 비프음 발생
            try { Thread.sleep(500); } catch(Exception e) {} // 0.5초간 일시정지
        }
 
        for(int i=0; i<5; i++) {
            System.out.println("띵");
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}
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
28
29
30
31
32
33
34
35
36
37
38
39
package sec02.exam01_createthread;
 
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) {}
            }
        });*/
        
        thread.start();
        
        for(int i=0; i<5; i++) {
            System.out.println("띵");
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
package sec02.exam01_createthread;
 
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) {}
        }
    }
}
cs



12.2.2 Thread 하위 클래스로부터 생성

// 작업 스레드가 실행할 작업을 Runnable로 만들지 않고, Thread의 하위 클래스로 작업 스레드를 정의 하면서 작업 내용을 포함시킬 수도 있다.

* start() 메소드는 두번 사용할 수 없다



 

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
28
29
30
package sec02.exam01_createthread;
 
import java.awt.Toolkit;
 
public class BeepPrintExample3 {
    public static void main(String[] args) {
        //how1
        Thread thread = new BeepThread();
        
        //how2
        /*Thread thread = new Thread() {
            @Override
            public void run() {        
                Toolkit toolkit = Toolkit.getDefaultToolkit();    
                for(int i=0; i<5; i++) {        
                    toolkit.beep();
                    try { Thread.sleep(500); } catch(Exception e) {}
                }
            }
        };*/
        
        
        thread.start();        
        
        for(int i=0; i<5; i++) {
            System.out.println("띵");
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
package sec02.exam01_createthread;
 
import java.awt.Toolkit;
 
public class BeepThread extends Thread {
    @Override
    public void run() {        
        Toolkit toolkit = Toolkit.getDefaultToolkit();    
        for(int i=0; i<5; i++) {        
            toolkit.beep();
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}
cs



12.2.3 스레드의 이름

- 메인 스레드 이름 : main

- 작업 스레드 이름 : Thread-n


- 작업 스레드의 이름 얻기


- 작업 스레드의 이름 변경


- 코드를 실행하는 스레드의 참조 얻기



mainThread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package sec02.exam02_threadname;
 
public class ThreadNameExample {
    public static void main(String[] args) {
        Thread mainThread = Thread.currentThread(); // 이 코드를 실행하는 스레드 객체 얻기
        System.out.println("프로그램 시작 스레드 이름: " + mainThread.getName());
        
        ThreadA threadA = new ThreadA(); // ThreadA 생성
        System.out.println("작업 스레드 이름: " + threadA.getName());
        threadA.start();
        
        ThreadB threadB = new ThreadB(); // ThreadB 생성
        System.out.println("작업 스레드 이름: " + threadB.getName());
        threadB.start();
    }
}
 
cs



ThreadA

1
2
3
4
5
6
7
8
9
10
11
12
13
package sec02.exam02_threadname;
 
public class ThreadA extends Thread {    
    public ThreadA() {
        setName("ThreadA"); // 생성자에서 스레드 이름 설정 // 원래 Thread-0부터 출력
    }
    
    public void run() {        
        for(int i=0; i<2; i++) {        
            System.out.println(getName() + "가 출력한 내용");
        }
    }
}
cs



ThreadB

1
2
3
4
5
6
7
8
9
package sec02.exam02_threadname;
 
public class ThreadB extends Thread {    
    public void run() {    
        for(int i=0; i<2; i++) {        
            System.out.println(getName() + "가 출력한 내용");
        }
    }
}
cs







Posted by 너래쟁이
: