Concurrent Programming

구름코딩·2020년 10월 9일
1

java8 _ 더 자바

목록 보기
14/23

Concurrent software

  • 동시에 여러 작업을 할 수 있는 소프트웨어
  • 프로그래밍을 하면서 동영상 강의듣기 등

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

  • 멀티 프로세싱
  • 멀티 스레드

자바 멀티 스레드 프로그래밍

  • Thread / Runnable

Thread클래스 상속받아서 사용하기

main(){
  myThread myThread = new myThread();
  myThread.start(); <-- 실행하면 Thread 출력해야댐

  System.out.println("Hello "+Thread.currentThread().getName());
}
static class myThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread " + Thread.currentThread().getName());
    }
}
//output
Hello main <-- 근데 hello가 먼저나옴
Thread Thread-0

순서상 Thread가 나오고 Hello가 나올거같지만 간혹 순서가 바뀌어서 나오기도한다 (순서 보장x)

Runnable()사용해서 Thread사용하기

Thread thread1 = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Thread " + Thread.currentThread().getName());
    }
});

람다식으로 전환

  • sleep()을 이용한 쓰레드 대기
Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000L); <-- 1초 대기
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Thread " + Thread.currentThread().getName());
}
thread.start();
System.out.println("Hello "+Thread.currentThread().getName()); <-- 대기중인 쓰레드 대신 main쓰레드가 먼저 실행된다 (순서 보장o)
//output
Hello main
Thread Thread-1
  • interruppt()를 이용한 쓰레드 깨우기
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;
        }
    }
});
thread.start(); <-- 무한루프 쓰레드 실행 1초마다 쓰레드 출력
System.out.println("Hello "+Thread.currentThread().getName()); <-- 스레드가 대기에 걸리므로 가장 먼저 main쓰레드로 출력
Thread.sleep(3000L); <-- 3초간 대기
thread.interrupt(); <- 자고있는 쓰레드 깨우기 => 무한루프 쓰레드의 try-catch에 걸려서 return 구문을 통해 탈출하게 된다
//출력
Hello main
ThreadThread-2
ThreadThread-2
ThreadThread-2
Exit!
  • join()을 이용한 쓰레드 대기후 합류
Thread thread = new Thread(() -> {
  try {
      Thread.sleep(3000L); <-- 3초 대기
  } catch (InterruptedException e) {
      throw new IllegalStateException(e);
  }
});
thread.start();
System.out.println("Hello " + Thread.currentThread().getName());
thread.join(); <-- thread가 다시 시작할때까지 기다렸다가 뒤의 코드를 실행(3초후)
System.out.println(thread + " is finished");

//출력
Hello main
<3초 대기>
Thread[Thread-2,5,] is finished

* join도 쓰레드를 기다리면서 대기하므로 join에도 try-catch문으로 보호해줘야한다

try {
	Thread.join();
} catch(InterruptedException e) {
	throw new IllegalStateException(e);
}

알고 있어야할 3가지 !

sleep() <- 대기를 걸면 main스레드의 우선순위를 올려서 먼저 처리후 sleep시간 이후에 나머지를 다른쓰레드에서 처리한다
Interrupt() <- 자고있는(대기중인) 쓰레드를 깨운다
join() <- 대기중인 쓰레드를 기다렸다가 다음 코드를 실행한다

*여기서 문제 - sleep()으로인해 대기중인 쓰레드에 접근하는 경우를 방지하기 위해 InterruptedException try-catch구문을 통해 제어를 하게되는데 join()또한 대기중인 쓰레드를 기다리기위해 대기중이므로 try-catch를 써서 보호해야한다. 따라서 수십 수백개의 쓰레드를 코드로 제어해야할 경우 상당히 복잡해지는 상황이 발생한다

profile
내꿈은 숲속의잠자는공주

0개의 댓글