From 9520eae97d366c08972d12456fe6e5884cdbf6fa Mon Sep 17 00:00:00 2001 From: shinsunyoung Date: Wed, 7 Apr 2021 14:31:28 +0900 Subject: [PATCH] =?UTF-8?q?=ED=94=84=EB=A1=9C=EA=B7=B8=EB=9E=A8=EC=9D=98?= =?UTF-8?q?=20=EB=8F=99=EC=9E=91=EC=9D=84=20=EC=8A=A4=EB=A0=88=EB=93=9C=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=EC=97=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8C=80=ED=95=98=EC=A7=80=20=EB=A7=90=EB=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4_\354\213\240\354\204\240\354\230\201.md" | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 "11\354\236\245/84_\355\224\204\353\241\234\352\267\270\353\236\250\354\235\230_\353\217\231\354\236\221\354\235\204_\354\212\244\353\240\210\353\223\234_\354\212\244\354\274\200\354\244\204\353\237\254\354\227\220_\352\270\260\353\214\200\354\247\200_\353\247\220\353\235\274_\354\213\240\354\204\240\354\230\201.md" diff --git "a/11\354\236\245/84_\355\224\204\353\241\234\352\267\270\353\236\250\354\235\230_\353\217\231\354\236\221\354\235\204_\354\212\244\353\240\210\353\223\234_\354\212\244\354\274\200\354\244\204\353\237\254\354\227\220_\352\270\260\353\214\200\354\247\200_\353\247\220\353\235\274_\354\213\240\354\204\240\354\230\201.md" "b/11\354\236\245/84_\355\224\204\353\241\234\352\267\270\353\236\250\354\235\230_\353\217\231\354\236\221\354\235\204_\354\212\244\353\240\210\353\223\234_\354\212\244\354\274\200\354\244\204\353\237\254\354\227\220_\352\270\260\353\214\200\354\247\200_\353\247\220\353\235\274_\354\213\240\354\204\240\354\230\201.md" new file mode 100644 index 0000000..c59786f --- /dev/null +++ "b/11\354\236\245/84_\355\224\204\353\241\234\352\267\270\353\236\250\354\235\230_\353\217\231\354\236\221\354\235\204_\354\212\244\353\240\210\353\223\234_\354\212\244\354\274\200\354\244\204\353\237\254\354\227\220_\352\270\260\353\214\200\354\247\200_\353\247\220\353\235\274_\354\213\240\354\204\240\354\230\201.md" @@ -0,0 +1,114 @@ +# item 84. 프로그램의 동작을 스레드 스케줄러에 기대하지 말라 + +# 🧭 스레드 스케줄러 + +> 여러 스레드가 실행 중이면 운영체제의 **스레드 스케줄러**가 어떤 스레드를 얼마나 오래 실행할지 정한다. + +## 스레드 스케줄러란? + +![Untitled](https://user-images.githubusercontent.com/42836576/113815194-bd89e780-97ad-11eb-939c-f41ce7994239.png) + +- **스레드의 실행 시점을 관리**하는 역할을 한다. + - 언제 실행 가능한 상태로 움직여야할지 + - 언제 실행중인 상태를 종료해야할지 + - 종료했을 때 스레드를 어디로 보내야할지 + - ... +- 사용자가 제어할 수 없다. +- 제한된 자원을 여러 프로세스가 효율적으로 사용하도록 다양한 정책(Policy)을 가지고 할당한다. → 즉, **운영체제**마다 달라질 수 있다. + +> 정확성이나 성능이 스레드 스케줄러에 따라 달라지는 프로그램이라면 다른 플랫폼에 이식하기 어렵다. + +```jsx +// 이식이 어려운 프로그램을 만들고 있는 🐱‍💻 +🐱‍💻 : 이 프로그램은 A 스케줄링 정책에 맞춰 작성해야지! + macOS 기반에서 A 정책은 우선순위가 높으니까 제대로 돌아갈거야! + +// 이식성이 좋은 프로그램을 만들고 있는 🐰 +🐰 : 프로세스 수가 n개니까 스레드 개수가 너무 많아지지 않게 조절해야겠다. + (기본 최대값은 프로세스당 250개의 스레드) +``` + +# 🦉 실행 가능한 스레드 수를 적게 유지하기 + +실행 가능한 스레드 = 대기(waiting) 상태인 스레드 + +## 1. 당장 처리해야할 작업이 없다면 실행하지 않기 + +- 스레드 풀 크기를 적절히 설정하고, 작업은 짧게 유지해야 한다. + - 단, 너무 짧으면 오히려 작업 분배에 부담이 가서 성능을 떨어뜨릴 수 있다. + - **바쁜 대기(busy waiting)** 상태가 되면 안된다. + - 기다리는 스레드가 공유 자원을 사용할수 있는지 없는지 계속해서 무한 루프를 돌면서 조건문을 체크하는 방식 + + ```jsx + // 바쁜 대기 버전 CountDownLatch 구현 + public class SlowCountDownLatch { + privateint count; + + public SlowCountDownLatch(int count) { + if (count < 0) + throw new IllegalArgumentException(count + " < 0"); + this.count = count; + } + + public void await() { // 바쁜 대기 중 (so bad ~~~) + while (true) { + synchronized(this) { + if (count == 0) + return; + } + } + } + + public synchronized void countDown() { + if count != 0) + count--; + } + } + ``` + + - 스레드 스케줄러의 변덕에 취약하다. + - 프로세서에게 부담을 주기 때문에 다른 유용한 작업이 실행될 기회를 박탈한다. + + → **성능**과 **이식성**이 떨어진다. + +# 🔥 하지말아야 할 것들 + +## 1. Thread.yield + +### 가 뭐지? + +- 다른 스레드에게 실행을 양보하는 메서드 + +```jsx +🐱‍💻 : A 스레드에 비해 B 스레드는 CPU 시간이 적으니까, yield()를 사용해서 시간을 조절하자! +``` + +### 하지말자 + +- 오히려 성능이 나빠질 수도 있다. +- **테스트할 수단도 없다.** + +→ 차라리 애플리케이션 구조를 바꿔 동시 대기 상태의 스레드 수가 적어지도록 하자 + +## 2. Thread Priority + +### 가 뭐지? + +- 스레드의 우선순위 + +```jsx +🐱‍💻 : 스레드 스케줄링 전략은 우선순위에 따라 바뀌니까 우선순위를 조절해야겠다! +``` + +### 하지말자 + +- 이미 잘 동작하는 프로그램의 서비스 품질을 높이기 위해 드물게 쓰일 수는 있다. + - 그러나 거의 동작하지 않는 프로그램을 "고치기 위해" 사용하면 절대 안 된다. +- 스레드 우선순위는 이식성이 가장 나쁜 특성에 속한다. + +→ 진짜 원인을 찾아 수정하자 + +# 🥱 결론 + +- 프로그램의 동작을 스레드 스케줄러에 기대지 말자 +- Thread.yield와 스레드 우선순위에 의존하지도 말자 \ No newline at end of file