CH07 - Barriers
1 Race Condition
Data Race와 Race Condition 차이는?
실전에서, 많이 data race 때문에 Race Condition 가 발생하곤 한다.
근데 서로 dependent 하지 않다.
계산 순서가 뒤바뀌면, 은 전형 다른 값이나온다.
예를들어, 올리비아는 파티를 위해 기존에 1개있던 chips에 3개를 더사자고 더하고 배런은 거기에 넉넉히 먹기 위해 2배를 더한다. 근데, 순서가 바뀌게 되면, (1+3)x2 와 (1x2)+3
불행히도, Race Condition 완전히 감지하기 위한 방법은 없다.
대응 방법: use sleep statement to modify timing and execution order
코드설명: 각 5개의 쓰레드를 가진 올리비아와 배런은 파티를 위해 chips를 사려고 한다. 현재 집에 1개가 있다. 배런은 2개씩 곱해주고, 올리비아는 3개씩 더한다.
특징: ReentrantLock을 사용하여 data race는 발생하지 않지만, 배런과 올리비아의 상대적인 실행 순서 변경으로 인해 race condition은 발생하는 상황
class Shopper extends Thread {
public static int bagsOfChips = 1; // start with one on the list
private static Lock pencil = new ReentrantLock();
public Shopper(String name) {
this.setName(name);
}
public void run() {
if (this.getName().contains("Olivia")) {
pencil.lock();
try {
bagsOfChips += 3;
System.out.println(this.getName() + " ADDED three bags of chips.");
} finally {
pencil.unlock();
}
} else { // "Barron"
pencil.lock();
try {
bagsOfChips *= 2;
System.out.println(this.getName() + " DOUBLED the bags of chips.");
} finally {
pencil.unlock();
}
}
}
}
public class RaceConditionDemo {
public static void main(String args[]) throws InterruptedException {
// create 10 shoppers: Barron-0...4 and Olivia-0...4
Shopper[] shoppers = new Shopper[10];
for (int i = 0; i < shoppers.length / 2; i++) {
shoppers[2 * i] = new Shopper("Barron-" + i); // 5명 배런 생성
shoppers[2 * i + 1] = new Shopper("Olivia-" + i); // 5명 올리비아 생성
}
for (Shopper s : shoppers)
s.start();
for (Shopper s : shoppers)
s.join();
System.out.println("We need to buy " + Shopper.bagsOfChips + " bags of chips.");
}
}해결방법: Barrier
2 Barrier
Barrier란?
코드설명: 결과값이 계속 다르게 나오는 위와 다르게 bagsOfChips가 계속 512개로 나오는 것 확인가능.
CyclicBarrier.await()사용다른메서드
int getParties(): barrier를 넘어야되는 모든 쓰레드들의 개수
int getNumberWaiting(): barrier에서 현재 기다리는 쓰레드 개수
void reset(): barrier를 초기 상태로 만든다
boolean isBroken(): broken 스레드가 있는지
3 CountDownLatch
멀티 쓰레드에서 모든 동작이 끝나기를 기다려야 하는 상황이라면 join 을 사용하기 조금 난감하다. 이럴 땐 CountDownLatch 를 사용하면 편리하다.
메서드
CountDownLatch(value): count값 초기화.
await(): count 값이 0이 될때까지 기달.
countDown(): count 값 내리기.
CyclicBarrier와 CountDownLatch 차이
CyclicBarrier: 특정 스레드 수가 기다리고 있을때 릴리즈
CountDownLatch: count 값이 0에 도달했을때 릴리즈
주의할점: 만약 위의 코드 CountDownLatch에 capacity를 10을 줬다하면 프로그램이 멈춰버린다. 이유 생각해보기.
흔한 사용 방법 CountDownLatch
count를 1로 초기화
간단한 on/off 게이트
count를 N으로 초기화
N 쓰레드가 특정 업무를 끝날때 까지 기다린다.
or 특정 업무가 N번 진행될때까지 기다린다.
QUIZ
Which scenario describes a potential use case for a CountDownLatch initialized to a count value of 1?
Multiple threads need to wait until after one other thread completes some action to continue
What is true about Java's CountDownLatch?
It releases when its counter value reaches zero.
A thread that needs to execute a section of code before the barrier should call the CyclicBarrier's
_____method_____executing the code.await(); after
Barriers can be used to control
_____.the relative order in which threads execute certain operations
Which of these is responsible for causing a race condition?
the OS execution scheduler (The order in which the OS schedules threads to execute is non-deterministic)
A race condition
_____a data race.can occur independently of
Which scenario creates the potential for a race condition to occur?
A single-threaded program is competing with other processes for execution time on the CPU.
Two threads are concurrently reading and writing the same shared variable.
One thread is modifying a shared variable while another thread concurrently reads its value.
The order in which two threads execute their respective operations will change the output. (픽)
Last updated