JAVA/수업 복습

자바 공부기록 55 - Thread

본이qq 2022. 5. 12. 16:31

● Thread : 프로그램의 명령을 실행하게끔 해주는 실행 주체.
개발자가 별도의 Thread를 생성하지 않는 다면,
한 프로그램에 하나의 Thread가 존재하여 해당 명령을 차례 차례 순서대로 실행시킴

 

-프로그램의 수행 중 동시에 처리하고자 하는 작업이 생겼을 때는 원래 갖고 있는 메인 Thread 외에
  Thread 클래스를 추가사용하여 실행시킬 수 있습니다.
-Thread Class : 프로그램 실행의 흐름을 분기할 수 있는 방법을 제공하는 클래스

 

 

 

●구현방법
1. Thread 클래스를 상속받는 방법
   1-1. Thread 클래스를 상속받아 public void run() 메서드를 오버라이딩합니다.
         public void run() : 쓰레드가 생성되어 수행할 작업을 정의하는 메소드
   1-2. 해당 클래스의 객체를 생성하고, start 메서드를 호출(실행)합니다.
        만약 오버라이딩된 run 메서드를 호출하면, 쓰레드 생성실행이 아니라,
        일반 메서드 호출이 되므로 반드시 start 메서드를 통해 run 으로 이어지게 호출합니다.

-start 메서드 : Thread 클래스( 부모 클래스 ) 에 있는 메서드로, 자체적으로 쓰레드 추가
                  생성 후, run 메서드를 재호출하는 역할을 합니다. (상속된 메서드로 메서드가 표면에 보여지지 않은 채

                  사용됩니다)
2. Runnable 인터페이스를 implements(구현)하는 방법

     2-1. Runnable 인터페이스를 구현하는 클래스 작성
     2-2. public void run() 오버라이딩 구현
     2-3. 해당 클래스의 A 객체 생성
     2-4. A 객체를 Thread 클래스의 생성자로 전달하여 Thread 객체 생성
     2-5. 생성시킨 쓰레드의 start 메소드 호출!

.

 

 

 

Thread 클래스를 상속받기

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class ThreadB1 extends Thread{
    public void run() {
        for(int i=1; i<=10; i++) {
            System.out.println("ThreadB1 : i -> " + i);
            try {
                sleep(500);
                //Thread.sleep(500); 앞에 Thread. 을 굳이 안써도됨 
                //Thread 클래스를 상속한 클래스는 sleep 메서드도 물려받았을 것이므로 
                //클래스 이름을 앞에 붙이고 사용하지 않아도 됩니다. 
                //sleep 메서드는 프로세서 실행에 관여하는 명령이라서 예외처리가 따라다닙니다. 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
class ThreadB2 extends Thread{
    public void run() {
        for(int i=1; i<=10; i++) {
            System.out.println("ThreadB2 : i -> " + i);
            try {
                sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
public class Thread02 {
 
    public static void main(String[] args) {
        ThreadB1 b1 = new ThreadB1();
        ThreadB2 b2 = new ThreadB2();
        //b1.run();
        //b2.run();
        b1.start();
        b2.start();
        
        for(int i=1; i<=10; i++) {
            System.out.println("main : i -> " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
 
    }
 
}
cs

-> ThreadB1 , ThreadB2, main 쓰레드 실행

 

 

 

 

 

Runnable 인터페이스를 implements(구현)하기

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package days32;
 
//2. Runnable 인터페이스로 구현하는 방법
//2-1. Runnable 인터페이스를 구현하는 클래스 작성
//2-2. public void run() 오버라이딩 구현
//2-3. 해당 클래스의 A 객체 생성
//2-4. A 객체를 Thread 클래스의 생성자로 전달하여 Thread 객체 생성
//2-5. 생성시킨 쓰레드의 start 메소드 호출!
 
class ThreadD1 implements Runnable{
    public void run() {
        for(int i=1; i<=10; i++) {
            System.out.printf("ThreadD1 : i -> %d\n" , i);
            try {
                Thread.sleep(500);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
class ThreadD2 implements Runnable{
    public void run() {
        for(int i=1; i<=10; i++) {
            System.out.printf("ThreadD2 : i -> %d\n" , i);
            try {
                Thread.sleep(500);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
}
public class Thread04 {
 
    public static void main(String[] args) {
        //Runnable 인터페이스를 구현한 쓰레드 생성
        //1. Runnable 인터페이스를 구현한 클래스의 객체 생성
        ThreadD1 t1 = new ThreadD1();
        //2. 1에서 생성된 객체를 Thread생성자에 전달인수로 전달하며 Thread 객체 생성 
        Thread t = new Thread(t1);
        //3. 2에서 생성된 Thread 객체를 사용하여 start 메소드 호출
        t.start();
        
        //위의 과정을 한 라인으로 작성한 코드
        new Thread(new ThreadD2()).start();
        
        for(int i=1; i<=10; i++) {
            System.out.printf("main: i -> %d\n", i);
            try {
                Thread.sleep(500);
            } catch(InterruptedException e ) {
                e.printStackTrace();
            }
        }
        
 
    }
 
}
 
cs

-> ThreadB1 , ThreadB2, main 쓰레드 실행

 

 

 

 

○ 익명 클래스를 활용한 쓰레드 생성
  익명 클래스 : 메소드를 오버라이딩하면서 객체를 생성하는 방법

 

 

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
public class Thread05 {
 
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                for(int i=1; i<=10; i++) {
                    System.out.printf("익명클래스 : i -> %d\n", i);
                    try {
                        Thread.sleep(500);
                    }catch(InterruptedException e ) {
                        e.printStackTrace();
                    }
                }
                
            }
            
        }.start();
        for(int i=1; i<=10; i++) {
            System.out.printf("main : i -> %d\n", i);
            try {
                Thread.sleep(500);
            }catch(InterruptedException e ) {
                e.printStackTrace();
            }
 
    }
 
}
}
 
 
cs

->익명의 쓰레드, main 실행

 

 

○ 쓰레드 멈추기

 

-boolean을 매개변수로 갖는 메서드를 만들어주고, run 메서드를 오버라이딩 할때, 조건에 boolean 값이 true여야한다는 것을 추가한다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ThreadE extends Thread{
 
    //스레드를 계속 실행할지를 판단할 변수 생성
    private boolean state = true;
    
    
    //state 변수값을 변경할 수 있는 멤버 메서드 생성
    
    public void setState(boolean s) {
        this.state = s;
    }
    public void run() {
            //반복 실행이 계속될때마다, 스레드 실행 여부가 검사됩니다.
            for(int i=10; i>0 && state ==true ; i--) {
                System.out.println(i);
                try {
                    sleep(1000);
                }catch(Exception e) {}
            }
            
        }
}
cs

 

->for문 안에 조건란에 i>0 && state == true 인 것에 주의

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Thread06 {
 
    public static void main(String[] args) {
        
            ThreadE t2 = new ThreadE();
            t2.start();
            
            String input = JOptionPane.showInputDialog("정답을 입력하세요");
            
            // t2 스레드를 멈추는 위치
            t2.setState(false);
            
            System.out.println("입력하신 값은" + input + "입니다");
    }
 
}
cs

-> input 에 값이 입력되면 ThreadE인 t2의 실행이 멈추게됨