리팩토링 (6)

멀티 스레드 환경에서 스레드 중단 및 복구, 종료

  • 멀티 스레드 환경에서 스레드 관리자의 리팩토링 전에 Java Concurrency In Practice의 7장 중단 및 종료를 복습하기로 함

자바에서 스레드의 종료

  • 자바에서 스레드가 작업을 실행하고 있을 때 강제로 멈추도록 하는 방법이 없다.
  • 물론 예전에는 있었다. Thread.stop()과 Thread.suspend()가 해당 기능을 제공하려 했는데, 지금은 deprecated되었다.

종료

사용자가 취소하기를 요청한 경우

  • 사용자가 직접 GUI에서 취소 버튼을 클릭하거나, 관리 인터페이스를 통해 작업을 취소하도록 요청한 경우.

시간이 제한된 작업

  • 일정한 시간 이내에 답이 될만한 결과를 계속해서 찾고 있다가, 제한된 시간이 지나면 그 동안 찾았던 결과 가운데 가장 좋은 값을 사용하도록 하는 프로그램

애플리케이션 이벤트

  • 원하는 결과를 얻기 위해 다양한 조건을 지정해 여러 작업을 동시에 실행하던 중 원하던 값을 얻으면 나머지 실행중이던 작업을 모두 취소한다.

오류

종료

취소 요청이 들어올때까지 계속해서 소수를 찾아내는 작업을 진행하고, 취소 요청 플래그를 사용해 작업을 멈춘다.

  • 안정적인 동작을 위해서는 cancelled 플래그가 volatile로 선언되어 있어야 한다. gist:ppzxc/a764693fb55983aee2df9e43d31c8b81#PrimeGenerator.java

소수 계산 작업 스레드를 실행시킨 다움 1초 후에 소수 계산 작업을 멈춘다.

  • 이렇게 종료하게 되면, 반드시 1초후에 종료하는 것을 보장하지 않는다.
  • 취소 요청 후 나머지 작업을 진행하기 위한 최소한의 시간이 필요하기 때문이다.
  • finally 구문 때문에, 슬립 도중 인터럽트가 걸려도, cancel은 반드시 호출 된다. gist:ppzxc/a764693fb55983aee2df9e43d31c8b81#aSecondOfPrimes.java

작업을 취소하려 할때에는 취소 정책이 명확해야 한다.

  • 외부 프로그램에서 작업을 취소하려 할 때 어떤 방법으로 취소 요청을 보낼 수 있는지, 작업 내부에서 취소 요청이 들어 왔는지를 언제 확인하는지, 취소 요청이 들어오면 실행 중이던 작업이 어떤 형태로 동작하는지 등에 대한 정보를 제공해야 안전하게 사용할 수 있다.

인터럽트

  • 스레드 내부에서 블로킹 되는 부분이 있다면, 큰 문제가 발생 할 수 있다.
  • 취소 요청이 들어왔는지 확인을 하지 못하는 경우가 생길 수 도 있으며, 영원히 종료되지 않는 프로그램이 되어버릴 수도 있다.

interrupt 메소드는 인터럽트를 걸고, isInterrupted는 해당 스레드에 인터럽트가 걸려 있는지 체크가 가능하며, interrupted 메소드를 호출하면 스레드의 인터럽트 상태를 해제하고, 해제 이전 값을 돌려준다.

인터럽트에 응답하지 않는 블로킹 작업

  • InputStream, OutputStream은 인터럽트에 반응하지 않는다.

스레드 기반 서비스 중단

Thanks to 객체 관련 책들!