본문 바로가기
Java/Java 기초문법

[JAVA 기초] 쓰레드(Thread) 1 - 쓰레드 생성방법1

by dev수니 2021. 4. 12.
반응형

 

 

 1  Thread(쓰레드) 생성

 

쓰레드는 기본적으로 1개의 쓰레드를 갖고 있다. 따라서 순차적 구조로 위에서 시작해 아래로 코드를 실행시킨다. 여기서 쓰레드를 새로 생성시키게 되면 2개 이상의 코드를 동시에 실행시킬 수 있다.

 

쓰레드의 생성방법 1

1. "extends Thread" 쓰레드 클래스를 상속받는 클래스를 작성한다. 

2. run()메서드를 오버라이드 한다.

3. 이 클래스를 기반으로 객체를 생성한다.

4. start() 호출하면 적절한 시전에 run() 메서드가 실행된다.

 

 

  • run()메서드를 직접호출하지 않는다. strat() 를 호출하면, 적절한 시점에 run()메서드가 자동으로 실행하게 된다. 
  • run()의 실행이 완료되면 해당 thread는 종료되고 소멸된다. 아직 실행중인 thread 가 하나라도 있으면 종료되지 않고 기다린다.

 

 

 

Ex

다음은 위의 생성방법1 을 통해 쓰레드를 만든 예제이다.

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
package Thread;
 
class MyThread extends Thread {
    String name;
    MyThread(String name) {     // 생성자:매개변수로 String name 전달
        this.name = name; 
        }
 
    @Override
    public void run() {
        for(int i=1; i<=5; i++) {
            System.out.println("이것은 쓰레드:" + name);
            try {
                sleep(1000);  // 1초동안 sleep. / ms 단위
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Extends_Thread {
    public static void main(String[] args) {
        MyThread t1 = new MyThread("첫번째 쓰레드");
        MyThread t2 = new MyThread("두번째 쓰레드");
        t1.start(); // 쓰레드 객체(t1)가 쓰레드로서 기능하게 됨.
        t2.start(); // 쓰레드 객체(t2)가 쓰레드로서 기능하게 됨. 
        System.out.println("메인쓰레드 실행종료.");
    }
}
cs

 

줄3에서 클래스를 만들고 Thread 클래스를 상속받는다. 

그리고 해당 클래스 내에서 실행할 구문을 적는다. 

방법2.에 해당되는 내용(run()메서드 오버라이딩) 을 줄10에서 한다. 해당 메서드 내에 for문으로 5번 반복, 생성자를 통해 객체 생성과 동시에 받는 값 name 을 for문 내에 출력한다. 그리고 sleep(1000); 하면 자동으로 빨간줄이 뜨면서 try / catch 문으로 작성하라고 뜨는데 그걸 눌러주면 위와 같이 try / catch 문이 작성된다.

sleep()ms 단위이기 때문에 1초일 경우 1000해주면 된다.

 

그리고 main() 에서 만들어준 쓰레드 객체 생성, name 매개변수로 집어넣을 구문을 같이 작성한다.

그리고 줄25,26에서 해당 메서드의 start() 메서드를 호출해준다. 그리고 나서 줄27 메인 메서드 내에서 출력해준다.

 

그러면 결과는 위와 같이 main() 메서드의 쓰레드가 먼저 실행되고, 그다음 t1, t2 인 것을 확인 할  수 있다.

총 실행되는 쓰레드는 3개이다. ( 1등 : main-thread / 2등 : t1 / 3등 : t2 )

 

 

 

 

 

 

Ex

다음은 "HELLO"를 1초마다 한번 총 5번 출력하는 프로그램이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package Thread;
 
class ThreadA extends Thread {
    String st;
    ThreadA(String st){
        this.st = st;
    }
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(st);
        }
    }
}
public class Thread_Hello {
    public static void main(String[] args) {
        ThreadA th = new ThreadA("HELLO");
        th.start();
    }
}
cs

 

위의 경우 Thread 객체 생성시 매개변수HELLO를 입력받고 그 HELLO값을 String st 에 전달하여 run()메서드 내에서 sleep(1000) : 1초 후에 실행 하고 줄15에서 st 를 출력하는 구조이다. 이를 for문으로 묶어줘서 5번 반복되게 된다.

 

따라서 위 결과와 같이 출력된다.

 

 

 

 

 

 

Ex

다음은 "HELLO"와 "hello"를 1초마다 한번 총 5번 출력하는 프로그램이다.

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
package Thread;
 
class ThreadHello1 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("HELLO");
        }
    }
}
class ThreadHello2 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello");
        }
    }
}
public class Thread_Scanner {
    public static void main(String[] args) {
        ThreadHello1 he1 = new ThreadHello1();
        ThreadHello2 he2 = new ThreadHello2();
        he1.start();
        he2.start();
    }
}
cs

 

위의 예제를 이용해서 HELLO와 hello를 출력하는 쓰레드두개 생성시켜준 것이다. 따라서 결과는 다음과 같이 출력된다.

 

 

 

 

 

 

Ex

문자열을 입력받고 한글자씩 출력하는 쓰레드 (0.5초에 한글자씩)

문자열 입력 : Hello, I'm Java 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
package Thread;
 
import java.util.Scanner;
 
class ThreadString extends Thread{
    String str;
    ThreadString(String str){
        this.str = str;
    }
    public void run() {
        for (int i = 0; i < str.length(); i++) {
            System.out.print(str.charAt(i));
            try {
                sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Thread_Scanner {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("문자열 입력 : ");
        String str = sc.nextLine();
        
        ThreadString th = new ThreadString(str);
        th.start();
        sc.close();
    }
}
cs

 

줄23~25에서 메인에서 Scanner 객체를 생성해서 문자열을 입력받고 해당 문자열을 str 에 저장시켜주었다.

 

그리고 줄5~8에 Thread 를 상속받는 ThreadString 클래스를 생성하여 객체 생성과 동시에 문자열을 생성자를 통해 입력받게 하였고 입력받은 매개변수를 String 타입으로 변수 str에 저장시켜 주게 했다. 

 

그리고 줄10에서 run() 메서드의 오버라이딩을 통해 start()를 호출하면 작동할 구문을 작성하였는데 작성한 구문은 줄11에서 for문을 이용하여 str의 길이만큼 반복하고 줄12에서 str의 문자를 하나씩 출력하는 것이다. 이를 위해 str.charAt(i)charAt() 을 사용해주었다.

그리고 0.5초에 한번씩 출력하기 위해 줄13에서 try catch 문으로 sleep() 메서드를 작성해주었다.

 

그리고 줄27에서 객체를 생성과 동시에 매개변수로 입력받은 문자열을 저장한 str매개변수로 넣어주었고 28에서 star() 를 호출하였다.

 

 

 

 

 

Ex

다음 예제는 점수를 입력받고 O X 를 표시해주는 프로그램이다.

입력 : 5 1 3 3 2   ---> 문자열 --> int[] (.split())
정답 입력 : 5 1 3 3 3
채점 결과 : O O O O X (총점 : 80점)

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
package exception;
 
import java.util.Scanner;
 
class Array {
    int[] arr;
    
    Array(String s){
        String[] arrS = s.split(" ");    // 문자열에서 구분자" "를 이용해 데이터를 배열에 저장
        this.arr = new int[arrS.length];
        for (int i = 0; i < arr.length; i++) {
            this.arr[i] = Integer.parseInt(arrS[i]);
        }
    }
}
 
class Thread_Score extends Thread {
    int[] arr1;
    int[] arr2;
    int count;
    Thread_Score(int[] arr1, int[] arr2) {
        this.arr1 = arr1;
        this.arr2 = arr2;
    }
    public void run() {
        System.out.println("채점결과 : ");
        for (int i = 0; i < arr1.length; i++) {
            try {
                sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(arr1[i]==arr2[i]) {
                count++;
                System.out.print("O ");
            }else 
                System.out.print("X ");
        }
        int score = (int)((double)count / arr1.length * 100);
        System.out.println("(총점 : "+score+"점)");
    }
}
 
public class Thread_Array {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("입력 : ");
        String s1 = sc.nextLine();
        System.out.print("정답입력 : ");
        String s2 = sc.nextLine();
        
        Array arc1 = new Array(s1);
        Array arc2 = new Array(s2);
 
        Thread_Score th = new Thread_Score(arc1.arr,arc2.arr);
        th.start();
        sc.close();
    }
}
cs

 

정답을 입력할 클래스 Array 를 선언해주고 아래에서 scanner로 입력받을 문자열생성자에 담아서 사용한다. 생성자로 담아온 문자열을 구분자 문자열.split(" ") 를 이용해서 구분해 준 후 String 타입의 배열에 담아주고나서 해당 배열을 for문을 이용해서 줄6 int 형의 배열 arr에 담아준다. 그리고 this 를 사용해 위의 arr 에 값을 담아준다.

 

그리고 메인으로 내려와서 스캐너 객체 생성, 줄47~50 점수를 입력받고 답안을 입력받는다. 그리고 그 값을 String 타입으로 저장한다. 그리고 Array객체두개 생성해서 입력받은 문자열을 각각 생성자의 파라미터로 담아준다.

 

그리고 다시 줄17로 올라가 O, X, 점수를 낼수 있는 쓰레드를 생성한다.

여기에도 줄55에서 생성자를 통해 Array객체 내의 배열을 받아와 줄22,23에서 미리 선언해준 arr1arr2에 저장한다. 그리고 맞은 갯수를 저장할 count 변수도 선언해준다.

run() 메서드 오버라이딩을 통해 "채점결과 : " 를 입력한다. for 문 이용해서 arr[]값을 하나하나 비교해주고 ifarr1arr2값이 같을 경우 맞은갯수를 count++O를 표시, 아니면 X를 표시해준다. 그리고 이를 sleep() 를 이용해 0.5초에 한번씩 출력해준다.

그리고 for문이 끝나고 나면 int score 에 맞은 갯수를 나타내는 count 값과 총 문제 갯수를 나타내는 arr1.length나눠주는데 이들은 int형이기 때문에 정확한 값으로 나눠지지 않으므로 double형변환해서 나눠 준 후 1단위 이기 때문에 100을 곱해주고 나온결과를 int형으로 묶어서 형변환시켜준다.

 

 그리고 줄55로 내려가 쓰레드 객체를 생성하고 생성자 파라미터로 Array 객체의 arr값인 arc1.arrarc2.arr 을 각각 넣어준다. 그리고 start() 로 쓰레드 실행하면 위와 같이 나온다. 따라서 점수를 입력하고 정답을 입력하면 위와 같이 출력된다.

 

 

 

tip .split()

String s = "Java,going,Home !"

String[] arr = s.split(",")   // 콤마(,)로 구분 

arr[0] = "Java"

arr[1] = "going"

arr[2] = "Home"

arr[3] = "!"

 

반응형

댓글