728x90
반응형
1. thread 를 병렬로 처리하는 방법
- 동기화
- 병렬로 실행되는 스레드가 공유 리소스에 동시에 접근하려고 할 때, 무결성을 보장하기 위해 동기화 기법을 사용합니다. 동기화는 뮤텍스, 세마포어, 모니터 등의 다양한 기법이 존재
- 뮤텍스
- 상호배제를 뜻하며, 한 번의 하나의 스레드만 공유 리소스에 접근할 수 있도록 제한합니다. 뮤텍스를 사용하여 공유 리소스에 접근하는 코드 영역을 임계 영역으로 지정하면, 동시에 여러 스레드가 해당 영역을 실행하지 못하게 됩니다.
- 세마포어
- 공유 리소스에 동시에 접근할 수 있는 스레드의 수를 제한하는 동기화 기법. 세마포어는 카운터를 사용하여 특정 시점에 동시에 실행할 수 있는 스레드 수를 제한합니다.
- 데드락
- 여러 스레드가 동시에 실행될 떄, 데드락이 발생. 데드락은 스레드들이 서로가 가진 리소스를 기다리며 진행이 멈추는 상황. 데드락을 처리하러며 아래와 같은 방법을 사용해야함
- 리스소 순서화 : 리소스를 사용하는 순서를 정하고 스레드들이 이 순서대로 리소스를 요청할수 있도록 한다.
- 타임아웃 설정 : 스레드가 특정 시간동안 리소스를 얻지 못하면 요청을 취소하고 다시 시도하도록 한다.
- 여러 스레드가 동시에 실행될 떄, 데드락이 발생. 데드락은 스레드들이 서로가 가진 리소스를 기다리며 진행이 멈추는 상황. 데드락을 처리하러며 아래와 같은 방법을 사용해야함
- 작업 분할 및 분산
- 병렬로 들어온 스레드를 효율적으로 처리하기 위해, 작업을 적절한 크기의 단위로 나누고, 스레드에 할당
- 최적화된 스레드풀 사용
- 과도한 스레드 생성 및 소멸로 인한 오버헤드를 줄이기 위해 스레드 풀을 사용할 수 있습니다.
2. thread 동시성 문제
- 락(lock) 사용
- 공유 리소스에 동시접근을 막기위해 락을 사용하고, 락을 사용하면 한 번에 하나의 스레드만 해당 리소스에 접근이 가능, java 에서는 synchronized 키워드를 사용하거나 reentrantLock을 사용
- 원자적(Atomic) 연산
- 원자적 연산은 여러 스레드에서 동시에 실행되더라도 중간 결과를 공유하지 않으므로 동시성 문제가 발생하지 않습니다. 자바에서는 AtomicInteger 와 같은 원자적 클래스를 사용할 수 있습니다.
- 뮤텍스
- 공유리소스에 접근하는 코드영역을 임계 영역으로 지정하여 동시에 여러 스레드가 해당 영역을 실행하지 못하도록 합니다.
- 세마포어
- 동시에 접근할 수 있는 스레드 수를 제한하여 동시성 문제를 해결하는 기법
- 모니터
- 객체 내부에서 뮤텍스와 조건 변수를 사용하여 동시성 문제를 해결하는 기법
import java.util.LinkedList; import java.util.Queue; public class ProducerConsumerMonitor { private final Queue<Integer> buffer; private final int maxSize; public ProducerConsumerMonitor(int maxSize) { this.maxSize = maxSize; this.buffer = new LinkedList<>(); } public synchronized void produce(int item) throws InterruptedException { while (buffer.size() == maxSize) { wait(); } buffer.add(item); System.out.println("Produced: " + item); notifyAll(); } public synchronized int consume() throws InterruptedException { while (buffer.isEmpty()) { wait(); } int item = buffer.remove(); System.out.println("Consumed: " + item); notifyAll(); return item; } public static void main(String[] args) { ProducerConsumerMonitor monitor = new ProducerConsumerMonitor(5); Thread producer = new Thread(() -> { for (int i = 0; i < 10; i++) { try { monitor.produce(i); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread consumer = new Thread(() -> { for (int i = 0; i < 10; i++) { try { monitor.consume(); } catch (InterruptedException e) { e.printStackTrace(); } } }); producer.start(); consumer.start(); } }
- 읽기-쓰기락 사용
- 읽기-쓰기 락은 여러 스레드가 동시에 읽기 작업을 수행하면서, 쓰기 작업은 독점적으로 수행하도록 제한하는 동기화 기법
728x90
반응형
'IT Diary > # Knowledge' 카테고리의 다른 글
[ Knowledge ] Redis(REmote DIctionary Server) 란? (0) | 2022.04.18 |
---|---|
[ Knowledge ] 주소창에 url을 입력하고 결과를 보는 과정 (0) | 2021.09.10 |
[ Knowledge ] Thread Safe란? (0) | 2021.09.09 |
빅오 표기법 (0) | 2021.08.29 |
[ Knowledge ] 디지털트랜스포메이션의 정의 (0) | 2021.06.14 |