자바에서 멀티스레딩(Multithreading)을 구현하는 방법은?
_____A: 하나의 프로세스 내에서 여러 개의 경량 실행 흐름(스레드)을 동시에 또는 번갈아 수행하는 기법입니다. CPU 코어가 여러 개일 때 실제 병렬 실행이 가능하고, 하나의 코어만 있어도 시분할 방식으로 동시성(concurrency)을 구현합니다.
2. Q: Java에서 스레드를 생성하는 방법은 무엇이 있나요?
A: 크게 세 가지 방법이 있습니다.
1) Thread 클래스 상속
class MyThread extends Thread {
@Override
public void run() {
// 작업 내용
}
}
new MyThread().start();
2) Runnable 인터페이스 구현
class MyTask implements Runnable {
@Override
public void run() { /* 작업 내용 */ }
}
new Thread(new MyTask()).start();
3) Callable
class MyCallable implements Callable
@Override
public String call() throws Exception {
return "결과";
}
}
ExecutorService es = Executors.newFixedThreadPool(2);
Future
String res = f.get();
3. Q: ExecutorService와 스레드풀(Thread Pool)은 어떻게 사용하나요?
A: 직접 Thread를 만들지 않고 ‛Executors’ 유틸리티를 이용해 풀을 구성하면 재사용 효율과 관리가 편리합니다.
예)
ExecutorService executor = Executors.newFixedThreadPool(4);
for(int i=0; i<10; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " 실행");
});
}
executor.shutdown();
4. Q: 스레드 동기화(synchronization) 방법은 어떤 것이 있나요?
A: 공유 자원 접근 시 충돌을 막기 위해 아래 기법을 사용합니다.
- synchronized 키워드
• 메서드 동기화: public synchronized void m() {…}
• 블록 동기화: synchronized(this) {…}
- java.util.concurrent.locks 패키지
• ReentrantLock, ReadWriteLock 등
- Atomic 패키지: AtomicInteger, AtomicReference 등
5. Q: 스레드간 통신(inter-thread communication)은 어떻게 하나요?
A:
- Object.wait()/notify()/notifyAll()
synchronized 블록 내에서 조건을 기다리거나 알림
- BlockingQueue (예: ArrayBlockingQueue, LinkedBlockingQueue)
안전하게 생산자-소비자 패턴 구현
- CountDownLatch, CyclicBarrier 등
6. Q: 스레드 상태(Thread State)에는 어떤 것이 있나요?
A:
NEW – 생성 완료, start() 전
RUNNABLE – 실행 준비 또는 실행 중
BLOCKED – synchronized 잠금 대기 중
WAITING – wait(), join() 등 무기한 대기
TIMED_WAITING – sleep(), wait(timeout) 등
TERMINATED – run() 완료 또는 예외 종료
7. Q: 고급 동시성 유틸리티는 어떤 것들이 있나요?
A: java.util.concurrent 패키지에 다수 존재합니다.
- Executor, ThreadPoolExecutor, ScheduledExecutorService
- ForkJoinPool / RecursiveTask, RecursiveAction (분할정복 병렬 처리)
- CompletableFuture (비동기 콜백, 조합 연산)
- CountDownLatch, CyclicBarrier, Semaphore, Phaser, Exchanger
- ConcurrentHashMap, ConcurrentLinkedQueue, CopyOnWriteArrayList 등
8. Q: CompletableFuture는 어떻게 활용하나요?
A: 비동기 작업을 체인 형태로 결합하거나 에러 처리, 결과 조합이 가능합니다.
CompletableFuture.supplyAsync(() -> heavyTask(), executor)
.thenApply(result -> process(result))
.thenAccept(finalResult -> System.out.println(finalResult))
.exceptionally(e -> { e.printStackTrace(); return null; });
9. Q: Fork/Join 프레임워크의 특징과 사용 예시는?
A: 작업을 작은 단위로 분할(split)→병렬 실행→결과 병합(join)하는 구조. 대량 데이터 병렬 처리에 유리합니다.
ForkJoinPool pool = new ForkJoinPool(4);
RecursiveTask
Long result = pool.invoke(task);
10. Q: 스레드 안전(Thread-Safe)한 클래스를 구현하기 위한 팁은?
A:
- 불변객체(immutable) 설계
- 최소 단위로 동기화 범위 좁히기
- 상태 공유 최소화
- java.util.concurrent 유틸리티 적극 활용
- Deadlock, Livelock 방지 전략(락 획득 순서 통일, 제한 시간)
— 이상이 Java에서 멀티스레딩을 구현·관리하기 위한 주요 개념과 기법에 대한 FAQ입니다.
이 두 가지 방법을 통해 자바에서 멀티스레드를 생성하고 관리할 수 있습니다.
1. Thread 클래스 상속하기자바에서 `Thread` 클래스를 직접 상속받아 새로운 스레드를 생성할 수 있습니다.
이 방법은 스레드의 동작을 정의하는 `run()` 메서드를 오버라이드하여 구현합니다.
```javaclass MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " - Count: " + i); try { Thread.sleep(1000); // 1초 대기 } catch (InterruptedException e) { e.printStackTrace(); } } }}public class Main { public static void main(String[] args) { MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); thread1.start(); // 스레드 시작 thread2.start(); // 스레드 시작 }}```
2. Runnable 인터페이스 구현하기`Runnable` 인터페이스를 구현하는 방법은 스레드의 동작을 정의하는 `run()` 메서드를 포함하는 클래스를 작성하고, 이를 `Thread` 클래스의 생성자에 전달하여 스레드를 생성하는 방식입니다.
이 방법은 다중 상속이 필요한 경우 유용합니다.
```javaclass MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " - Count: " + i); try { Thread.sleep(1000); // 1초 대기 } catch (InterruptedException e) { e.printStackTrace(); } } }}public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread1 = new Thread(myRunnable); Thread thread2 = new Thread(myRunnable); thread1.start(); // 스레드 시작 thread2.start(); // 스레드 시작 }}```
3. 스레드의 상태스레드는 다음과 같은 여러 상태를 가질 수 있습니다:- NEW : 스레드가 생성되었지만 아직 실행되지 않은 상태.- RUNNABLE : 스레드가 실행 중이거나 실행 대기 중인 상태.- BLOCKED : 다른 스레드에 의해 잠금이 걸려 실행되지 않는 상태.- WAITING : 다른 스레드의 특정 작업이 완료되기를 기다리는 상태.- TIMED_WAITING : 지정된 시간 동안 대기하는 상태.- TERMINATED : 스레드의 실행이 완료된 상태.
4. 스레드 동기화멀티스레딩 환경에서는 여러 스레드가 동일한 자원에 접근할 때 데이터의 일관성을 유지하기 위해 동기화가 필요합니다.
자바에서는 `synchronized` 키워드를 사용하여 메서드나 블록을 동기화할 수 있습니다.
```javaclass Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; }}class MyRunnable implements Runnable { private Counter counter; public MyRunnable(Counter counter) { this.counter = counter; } @Override public void run() { for (int i = 0; i < 1000; i++) { counter.increment(); } }}public class Main { public static void main(String[] args) { Counter counter = new Counter(); Thread thread1 = new Thread(new MyRunnable(counter)); Thread thread2 = new Thread(new MyRunnable(counter)); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Final Count: " + counter.getCount()); }}```
5. ExecutorService 사용하기자바 5부터는 `ExecutorService`를 사용하여 스레드 풀을 관리할 수 있습니다.
이는 스레드를 효율적으로 관리하고, 자원 낭비를 줄이는 데 유용합니다.
```javaimport java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class MyRunnable implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is executing."); }}public class Main { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(
3); for (int i = 0; i < 10; i++) { executorService.execute(new MyRunnable()); } executorService.shutdown(); // 모든 작업이 완료될 때까지 대기 }}``` 결론자바에서 멀티스레딩을 구현하는 방법은 다양하며, 각 방법은 특정 상황에 따라 장단점이 있습니다.
`Thread` 클래스를 직접 사용하는 방법은 간단하지만, `Runnable` 인터페이스를 사용하면 더 유연한 설계가 가능합니다.
또한, 스레드 동기화와 `ExecutorService`를 활용하면 멀티스레드 프로그래밍을 보다 효율적으로 관리할 수 있습니다.
멀티스레딩을 사용할 때는 항상 데이터의 일관성과 스레드 간의 상호작용을 신중하게 고려해야 합니다.
작성자:
최서진 [비회원]
| 작성일자: 1년 전
2024-09-05 03:57:03
조회수: 224 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 224 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.