[2021-02-27 토] TIL

노을·2021년 2월 28일
0

TIL

목록 보기
50/81
  • 지난 honux thread 수업을 복습하였고, 실습을 해보았다.
  • 과거 자바의 정석으로 스레드를 실습을 했을 때, 스레드를 사용해도 왜 느릴까?를 고민했었다.
    • 멀티 스레드를 통해 단 1개뿐인 표준출력을 이용했기 때문에 느린것이 당연한 것이었다.
      • IO 작업은 분산이 안된다.

1~N까지 더하기

  • 멀티 스레드 활용
   public class AddOneToN extends Thread{
    public AddOneToN(long start, long end){
        this.start = start;
        this.end = end;
    }
    private long start;
    private long end;
    //m 각각의 스레드가 더하는 건대, 변수를 공유함.
    public static long result;

    @Override
    public void run(){
        for(long i =start; i<= end;i++){  // 1부터 n까지  즉, end를 포함해야 연산이됨.
            result+=i;
            System.out.println(result);
        }
        System.out.println("thread ended ("+getName()+")");
    }
    public static void main(String[] args) throws InterruptedException {

        final long n = 1000_000L; // 스레드 작업량
        final int numThread = 3;
        Thread[] threadArray = new Thread[numThread];
        final long size = n/numThread; // 스레드로 일을 분산해서 처리하기 때문에 1/n 만큼의 업무량

        for(int i = 0 ; i< numThread; i++){
            long startTime = i*size+1; //예시. 0, 1*50+1, 2*50+1 ~
            long endTime = (i+1)*size; // 1*50, 2*50, 3*50~
            threadArray[i] = new AddOneToN(startTime,endTime);
        }

        long start = System.currentTimeMillis();

        for(Thread thread : threadArray){
            thread.start();
        }
        for(Thread thread : threadArray){
            thread.join();
        }
        long end = System.currentTimeMillis();
        System.out.println("경과 시간: "+(end-start));
        System.out.printf("sum of 1 to %d is %d",n, AddOneToN.result); // 1~100, 1000 이렇게 더하면 5와 0의 조합으로 이루어져야 정상

    }
}

결과가 이상하다?

1~1000 까지의 합 : 5와0의 조합인, 500500이다.

  • 멀티 스레드 : numThread = 3, start() 호출
    • 경과 시간: 28
      sum of 1 to 1000 is 498913
  • 단일 스레드 : numThread = 3, run() 호출
    • 경과 시간: 22
      sum of 1 to 1000 is 499500

왜 값이 틀린 것일까?

  • 공유 자원에 동시에 접근하여 동기화 문제가 발생한 것이다.
  • synchronized block 또는 method를 통해 공유자원에 Lock을 걸어 이러한 동기화 문제를 해결해야한다.
    • 단, synchronized는 객체에만 lock 을 걸 수 있다.

    • primitive type 은 synchronized 를 하여도, race condition 이 발생한다.
    • AtomicInteger 같은 클래스를 활용해보자.

미션 4 피드백 반영

  • 상속을 제거하고 포함관계로 재구성하였다.

참고

profile
카르페디엠

0개의 댓글