ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CompletableFuture (1) - 자바 Concurrent 프로그래밍 소개
    프로그래밍/Java 2022. 5. 6. 01:35

    CompletableFuture 을 학습하려면 이전까지의 Java Concurrent 프로그래밍을 알아야한다.

     

     

     

    Concurrent 소프트웨어


    • 동시에 여러 작업을 할 수 있는 소프트웨어
    • ex) 웹 브라우저로 유튜브를 보면서 키보드로 문서에 타이핑을 할 수 있다.
    • ex) 녹화를 하면서 인텔리J로 코딩을 하고 워드에 적어둔 문서를 보거나 수정할 수 있다.

     

     

     

    Java 에서 지원하는 Concurrent 프로그래밍


    • 멀티 프로세싱 (ProcessBuilder)
    • 멀티 쓰레드

    이번 시간에는 멀티 쓰레드에 관한것만 보자.

     

     

     

    Java 멀티 쓰레드 프로그래밍


    • Thread / Runnable

    아래는 쓰레드를 구현하는 두가지 방법이다. 

     

    1. Thread 를 상속받아 구현하는 방법

    // Thread 상속
    public static void main(String[] args) {
        HelloThread helloThread = new HelloThread();
        helloThread.start(); //Thread 생성
        
        System.out.println("hello : " + Thread.currentThread().getName());
    }
    static class HelloThread extends Thread {
        @Override
        public void run() {
            System.out.println("world : " + Thread.currentThread().getName());
    } }

     2. new Runable 를 람다를 이용하여 구현하는 방법

    // Runnable 구현 또는 람다
    Thread thread = new Thread(() -> System.out.println("world : " + Thread.currentThread().getName()));
    thread.start();
    System.out.println("hello : " + Thread.currentThread().getName());

    (참고) 실행을 해보면 메인 쓰레드와 일반 쓰레드의 순서는 보장되지 않는다.

    위 와 같이 쓰레드를 구현할 수 있고, 쓰레드 주요 기능 세 가지도 같이 알고 있어야 한다.

    • 현재 쓰레드 멈춰두기 (sleep)
      • 다른 쓰레드가 처리할 수 있도록 기회를 주지만 그렇다고 락을 놔주진 않는다.
        (
        잘못하면 데드락 걸릴 수 있겠죠.)
    public class Main {
      public static void main(String[] args) {
        Thread thread = new Thread(() -> {
          try{
            Thread.sleep(1000L);
          }catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println("Thread : " + Thread.currentThread().getName());
        });
        thread.start();
        System.out.println("Hello : " + Thread.currentThread().getName());
      }
      //Hello : main
      //Thread : Thread-0
    }
    • 다른 쓰레드 깨우기 (interupt)
      • 다른 쓰레드를 깨워서 interruptedExeption을 발생 시킨다.
      • 그 에러가 발생했을 때 할 일은 코딩하기 나름. 종료 시킬 수도 있고 계속 하던 일 할 수도 있다. 
    public class Main {
      public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
          while(true) {
            System.out.println("Thread : " + Thread.currentThread().getName());
            try{
              Thread.sleep(1000L);
            } catch (InterruptedException e) {
              System.out.println("exit!!!");
              return; // run() 은 return 타입이 void 이기 때문에 return; 시 종료된다.
            }
          }
        });
        thread.start();
        
        System.out.println("Hello : " + Thread.currentThread().getName());
        Thread.sleep(3000L);
        thread.interrupt(); //interrupted 자체는 종료시키는것이 아니라 깨우는것이다. catch 에서 받아 처리
        
        //Thread : Thread-0
        //Hello : main
        //Thread : Thread-0
        //Thread : Thread-0
        //exit!!!
      }
    }
    
    • 다른 쓰레드 기다리기 (join)
      • 다른 쓰레드가 끝날 때까지 기다린다.
    public class Main {
      public static void main(String[] args) {
        Thread thread = new Thread(() -> {
          System.out.println("Thread : " + Thread.currentThread().getName());
          try{
            Thread.sleep(3000L);
          } catch (InterruptedException e) {
            throw new IllegalStateException(e);
          }
        });
        thread.start();
    
        System.out.println("Hello : " + Thread.currentThread().getName());
        try {
          thread.join(); // 쓰레드가 끝날때까지 기다린다.
        } catch (InterruptedException e) {
          // 기다리고 있는 도중에 해당 main Thread 를 누군가 interrupt 할 경우 예외처리를 할 수 있는데, 이것이 문제이다.
          // 쓰레드가 많아질수록 이러한 복잡도는 더 증가!
          e.printStackTrace();
        }
    
        System.out.println(thread + " is finished");
      }
    }

    위 코드의 문제는 쓰레드가 증가할 수 록 interrupt 와 같은 예외처리 문제들이 점점 복잡해진다.

    수십, 수백개의 쓰레드를 이용할 경우 코드로 처리할 수 있는 복잡도가 크게 증가하여 Excutors 가 나오게 되었다. 

     

     

     

    참고


    인프런 - 백기선, Java8

    '프로그래밍 > Java' 카테고리의 다른 글

    CompletableFuture (4)  (0) 2022.05.06
    CompletableFuture (2) - Excutors  (0) 2022.05.06
    Date와 Time API  (0) 2022.05.05
    Optional  (0) 2022.05.05
    Stream  (0) 2022.05.04
Designed by Tistory.