add user agent parser and update build configuration
This commit is contained in:
225
docs/Concurrency.md
Normal file
225
docs/Concurrency.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# 자바 동시성(Concurrency) API 정리 및 쉬운 설명
|
||||
|
||||
자바의 동시성(Concurrency) API는 **멀티스레딩을 효율적으로 관리하고 안전하게 실행할 수 있도록 지원하는 기능**을 제공한다.
|
||||
즉, **여러 작업을 동시에 실행하여 프로그램 성능을 향상**시킬 수 있다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 주요 클래스 및 메서드 정리
|
||||
|
||||
### (1) `Thread` 클래스 (기본 스레드 실행)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `start()` | 새로운 스레드를 실행 |
|
||||
| `run()` | 실행할 코드 정의 (직접 호출하면 동작하지 않음) |
|
||||
| `sleep(ms)` | 지정된 시간(ms) 동안 스레드 일시 정지 |
|
||||
| `join()` | 현재 스레드가 종료될 때까지 다른 스레드 대기 |
|
||||
| `interrupt()` | 실행 중인 스레드를 인터럽트 (깨우기) |
|
||||
| `isAlive()` | 스레드가 실행 중인지 확인 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
class MyThread extends Thread {
|
||||
public void run() {
|
||||
System.out.println("스레드 실행 중!");
|
||||
}
|
||||
}
|
||||
|
||||
MyThread t = new MyThread();
|
||||
t.start(); // 스레드 실행
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### (2) `Runnable` 인터페이스 (스레드 실행)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `run()` | 실행할 코드 정의 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
class MyRunnable implements Runnable {
|
||||
public void run() {
|
||||
System.out.println("Runnable 스레드 실행!");
|
||||
}
|
||||
}
|
||||
|
||||
Thread t = new Thread(new MyRunnable());
|
||||
t.start();
|
||||
```
|
||||
→ `Thread` 클래스를 직접 상속하지 않고 `Runnable`을 구현하여 사용.
|
||||
|
||||
---
|
||||
|
||||
### (3) `ExecutorService` (스레드 풀)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `submit(Runnable)` | 스레드를 실행 (결과 없음) |
|
||||
| `submit(Callable<T>)` | 스레드를 실행하고 결과 반환 |
|
||||
| `shutdown()` | 스레드 풀 종료 (기존 작업 수행 후 종료) |
|
||||
| `shutdownNow()` | 즉시 모든 작업 중단 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
|
||||
executor.submit(() -> System.out.println("스레드 풀에서 실행"));
|
||||
executor.shutdown();
|
||||
```
|
||||
→ `Executors.newFixedThreadPool(2)`를 사용해 2개의 스레드를 관리.
|
||||
|
||||
---
|
||||
|
||||
### (4) `Callable` & `Future` (결과 반환이 필요한 작업)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `call()` | 실행할 코드 정의, 결과 반환 |
|
||||
| `get()` | `Future`에서 결과 가져오기 (블로킹) |
|
||||
| `isDone()` | 작업 완료 여부 확인 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
Callable<Integer> task = () -> {
|
||||
Thread.sleep(1000);
|
||||
return 10;
|
||||
};
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
Future<Integer> future = executor.submit(task);
|
||||
|
||||
System.out.println(future.get()); // 결과 가져오기
|
||||
executor.shutdown();
|
||||
```
|
||||
→ `Callable`을 사용하면 **스레드 실행 후 결과 값을 반환**할 수 있음.
|
||||
|
||||
---
|
||||
|
||||
### (5) `ReentrantLock` (락을 이용한 동기화)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `lock()` | 락 획득 |
|
||||
| `unlock()` | 락 해제 |
|
||||
| `tryLock()` | 락을 시도하고 성공하면 `true` 반환 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
System.out.println("임계영역 실행");
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
```
|
||||
→ `synchronized` 키워드 대신 `ReentrantLock`을 사용하여 더 정교한 동기화 가능.
|
||||
|
||||
---
|
||||
|
||||
### (6) `Semaphore` (동시 실행 제한)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `acquire()` | 리소스 사용 요청 (없으면 대기) |
|
||||
| `release()` | 사용한 리소스 반환 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
Semaphore semaphore = new Semaphore(2);
|
||||
|
||||
semaphore.acquire(); // 사용 가능하면 진행, 아니면 대기
|
||||
System.out.println("리소스 사용 중");
|
||||
semaphore.release();
|
||||
```
|
||||
→ 한 번에 2개의 스레드만 특정 코드 실행 가능.
|
||||
|
||||
---
|
||||
|
||||
### (7) `CountDownLatch` (스레드가 모두 끝날 때까지 대기)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `await()` | 모든 스레드가 완료될 때까지 대기 |
|
||||
| `countDown()` | 하나의 작업 완료 처리 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
new Thread(() -> {
|
||||
System.out.println("작업 완료");
|
||||
latch.countDown();
|
||||
}).start();
|
||||
}
|
||||
|
||||
latch.await();
|
||||
System.out.println("모든 작업 완료");
|
||||
```
|
||||
→ 모든 작업(`countDown()` 3회)이 끝나야 `await()`이 풀림.
|
||||
|
||||
---
|
||||
|
||||
### (8) `CyclicBarrier` (스레드가 모두 도달할 때까지 대기)
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------------------------------|
|
||||
| `await()` | 지정된 개수의 스레드가 모일 때까지 대기 |
|
||||
|
||||
**사용 예시:**
|
||||
```java
|
||||
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
|
||||
System.out.println("모든 스레드 도착!");
|
||||
});
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
new Thread(() -> {
|
||||
System.out.println("스레드 실행 중");
|
||||
barrier.await();
|
||||
}).start();
|
||||
}
|
||||
```
|
||||
→ `CyclicBarrier`는 정해진 개수의 스레드가 모두 도착할 때까지 기다림.
|
||||
|
||||
---
|
||||
|
||||
## 2. 자바 동시성 쉽게 설명하기
|
||||
|
||||
자바에서 동시성을 다룰 때 중요한 개념은 **멀티스레딩과 스레드 동기화**다.
|
||||
즉, 여러 개의 스레드가 **같은 자원을 동시에 접근하면 충돌이 발생**할 수 있으므로, 이를 적절히 제어해야 한다.
|
||||
|
||||
### 1️⃣ **기본적인 멀티스레드**
|
||||
- `Thread` 또는 `Runnable`을 사용해 실행
|
||||
- `start()`로 실행, `join()`으로 대기
|
||||
|
||||
### 2️⃣ **스레드 풀 사용 (`ExecutorService`)**
|
||||
- 직접 스레드를 생성하면 관리가 어렵기 때문에, **스레드 풀을 사용하여 성능 최적화**
|
||||
- `submit()`으로 작업을 실행하고, `shutdown()`으로 종료
|
||||
|
||||
### 3️⃣ **결과를 받아야 한다면? (`Callable` & `Future`)**
|
||||
- `Callable`을 사용하면 작업이 끝난 후 결과 값을 반환 가능
|
||||
- `future.get()`을 호출하면 결과를 가져올 수 있음
|
||||
|
||||
### 4️⃣ **공유 자원 충돌 방지 (`ReentrantLock`, `synchronized`)**
|
||||
- `synchronized` 키워드는 단순하지만 유연성이 낮음
|
||||
- `ReentrantLock`은 더 정교한 동기화 제공
|
||||
|
||||
### 5️⃣ **특정 조건을 만족할 때 실행 (`CountDownLatch`, `CyclicBarrier`)**
|
||||
- `CountDownLatch` → 여러 개의 스레드가 끝날 때까지 대기
|
||||
- `CyclicBarrier` → 여러 스레드가 동시에 도달해야 실행
|
||||
|
||||
---
|
||||
|
||||
## 3. 정리
|
||||
|
||||
✅ 멀티스레딩을 쉽게 하려면? → `ExecutorService`
|
||||
✅ 스레드 실행 결과를 받아야 한다면? → `Callable`, `Future`
|
||||
✅ 여러 스레드가 동시에 공유 자원을 사용하면? → `ReentrantLock`, `synchronized`
|
||||
✅ 여러 작업이 끝난 후 실행되게 하려면? → `CountDownLatch`, `CyclicBarrier`
|
||||
|
||||
즉, **자바 동시성 API를 적절히 활용하면 멀티스레딩을 효율적으로 관리할 수 있다!**
|
||||
Reference in New Issue
Block a user