프로그래밍Java 개발자

Java에서 스레드란 무엇이며, 스레드를 어떻게 생성하고 종료하는지, 다중 스레드 프로그램 구현 시 주의해야 할 점은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 역사:

Java에서는 다중 스레드 지원이 처음부터 구현되었습니다. 스레드는 여러 작업을 병렬로 수행할 수 있게 하여 다중 코어 프로세서를 효과적으로 사용할 수 있습니다. JVM은 운영 체제의 스레드 위에 추상화 레이어를 제공합니다.

문제:

스레드를 생성, 관리 및 종료하는 것은 그들의 생애 주기, 동기화 및 가능한 경쟁 상태에 대한 명확한 이해가 필요합니다. 스레드를 부주의하게 사용하면 교착 상태(deadlock), 자원에 대한 잘못된 접근 및 복잡한 오류 로그가 발생할 수 있습니다.

해결책:

Java에서는 Thread 클래스를 확장하거나 Runnable 인터페이스를 구현하여 스레드를 생성할 수 있으며, 최신 도구인 ExecutorService를 사용할 수 있습니다. 스레드를 올바르게 종료하고 생애 주기를 관리하며 공유 데이터에 대한 접근을 동기화하는 것이 중요합니다.

스레드 생성 및 종료 예:

class MyRunnable implements Runnable { public void run() { System.out.println("Thread is running"); } } public class ThreadExample { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); // 스레드 시작 try { t.join(); // 완료될 때까지 대기 } catch (InterruptedException e) { e.printStackTrace(); } } }

주요 특징:

  • 스레드는 run()이 아닌 start() 메서드를 사용하여 실행해야 합니다 (그렇지 않으면 실제 병렬성이 발생하지 않습니다).
  • 올바른 종료를 위해 join()을 사용하는 것이 중요합니다.
  • 종료된 스레드는 다시 시작할 수 없습니다: 새로운 start 호출은 IllegalThreadStateException을 발생시킵니다.

함정 질문.

스레드를 종료한 후에 다시 시작할 수 있나요?

아니요. 종료된 후 스레드는 "죽은" 것으로 간주되어, 다시 start()를 호출하면 IllegalThreadStateException이 발생합니다.

t.run() 호출과 t.start() 호출의 차이는 무엇인가요?

t.run()은 현재 스레드에서 run 메서드를 호출할 뿐이며, 새로운 실행 스레드를 만들지 않습니다. 오로지 t.start()만이 OS에 별도의 스레드를 생성합니다.

스레드가 처리되지 않은 예외로 종료되면 어떻게 되나요?

처리되지 않은 예외가 발생하면 스레드는 비정상적으로 종료되며, 스택 트레이스가 오류 스트림에 출력되고 다른 스레드에는 영향을 미치지 않습니다.

일반적인 실수 및 안티 패턴

  • start() 대신 run() 호출
  • 스레드 종료 시점을 놓침 (예: InterruptedException 처리 없음)
  • 종료 조건 없이 무한 스레드 만들기

실생활 사례

부정적인 사례

프로그래머가 run() 메서드를 사용하여 스레드를 실행하는데, 스레드가 메인과 병렬로 작동한다고 생각하지만 실제로는 모든 것이 순차적으로 실행됩니다.

장점:

  • 프로그램 로직이 올바르게 작동함

단점:

  • 병렬성이 없음, 실행 시간 최적화가 누락됨

긍정적인 사례

start()를 올바르게 사용하고, 예외를 적절히 처리하며, 스레드 종료를 대기하기 위해 join()을 사용하는 것.

장점:

  • 실제 병렬성
  • 관리되는 종료

단점:

  • 동기화를 주의해야 하며, 디버깅이 복잡해질 수 있음