진짜 개발자
본문 바로가기

Language/Java

Java - 멀티쓰레드 (Multi Thread)

728x90


멀티 쓰레드는 CPU를 최대한 활용할 수 있는 도움을 주었다

하지만 쓰레드는 이와 동시에 위험을 주었다

위험이란 원자적이지 못한 메소드를 여러개의 쓰레드가 동시에 접근하여 수행할때

그 결과값이 우리가 기대하는 값과는 다를 수 있다는 것이다.


아래 예시를 보자


----------------------------------------------------------------------------------------

*Count Class : 카운트 클래스는 num이라는 변수와 count()라는 num을 1씩 증가시키는 메소드를 가지고 있다

----------------------------------------------------------------------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Count{
 
    public int num;
 
    public void count() {
        try {
            Thread.sleep(1000);
             num++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
}
cs


----------------------------------------------------------------------------------------

*Task Class : Task 클래스는 Counter객체를 멤버변수로 가지고 있으며

                  스레드에서 counter객체의 num변수의 값이 5보다 작을때 까지만

                  count()메소드를 실행시킨다.

                 또한 Runnable을 구현하여 스레드 객체가 생성자에서 받을 수 있도록 한다.

----------------------------------------------------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Task implements Runnable{
 
    Counter counter = new Counter();
 
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(counter.num < 5)
            counter.count();
 
        System.out.println("수 : " + counter.num);
    }
 
}
cs


----------------------------------------------------------------------------------------

*Test Class : Test클래스는 두개의 스레드를 생성하며 Task를 인자로 넘겨 주어 수행한다                  

----------------------------------------------------------------------------------------
1
2
3
4
5
6
7
8
9
10
11
public class Test {
 
    public static void main(String[] args) {
        Task task = new Task();
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);        
 
        t1.start();
        t2.start();
    }
}
cs


----------------------------------------------------------------------------------------

*결과 : Task 클래스에서 While문의 조건이 5보다 작을때까지만 수행하라고 했으나 

         결과값은 6이 나왔다.

----------------------------------------------------------------------------------------

result : 수 : 5  // Thread1

    수 : 6  // Thread2




*** 이유 : count() 메소드의 num++ 값은 한줄의 코드로 원자적인것 처럼 보이나

             스레드가  1. 값에 접근하고 

                           2. 그값을 증가시키고 

                           3. 다시 그값을 적용하는 

              세 단계를 거친다 따라서 값을 증가시키고 그 값을 적용하기전 다른 스레드가

              그변수에 접근한다면 증가된값이 적용되기 이전의 값을 취하기 때문에 

              결과값이 다르게 나올 수 있다.


 ex) 

  Thread1 -> num ( 4 )    // 아직 num이 4이기 때문에 ++

  Thread2 -> num ( 4 )    // Thread2 가 접근했을 때에도 값이 4이기 때문에 ++

  

  Thread1 -> num ( 5 )    // Thread1이 count()를 실행하고 난 뒤 num은 5

  Thread2 -> num ( 6 )    // Thread2가 count()를 실행하고 난 뒤 num은 6



@@@ 해결법


   다음 포스팅에서 다루겠다