묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
오타 제보입니다.
11. 동시성 컬렉션 PDF 13 페이지당연한 이야기지만 다음과 같이 나누어 작성해도 된다.SimpleList basicList = new BasicList(); SimpleList proxyList = new SyncProxyList(basicList); test(list)강의 5:40 즈음 나오는 내용입니다. test() 에 proxyList 가 인자로 전달되어야하는데 pdf에는 test(list) 로 작성되어있네요. 감사합니다
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
멀티스레드일 때 테스트 결과 공유
영한님이 단일 스레드일 때 테스트 하셨는데요.멀티 스레드일 때 테스트 결과도 궁금하신 분들이 있을 것 같아 공유 드립니다 :)빠른 테스트를 위해서 sleep 은 사용하지 않았습니다. public class IncrementPerformanceMain { public static final int COUNT = 1_000_000; public static void main(String[] args) throws InterruptedException { test(new BasicInteger()); test(new VolatileInteger()); test(new SyncInteger()); test(new MyAtomicInteger()); } private static void test(IncrementInteger incrementInteger) throws InterruptedException { long startMs = System.currentTimeMillis(); Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < COUNT; i++) { incrementInteger.increment(); } } }; ArrayList<Thread> threads = new ArrayList<>(); for (int i = 0; i < 100; i++) { Thread thread = new Thread(runnable); threads.add(thread); thread.start(); } for (Thread thread : threads) { thread.join(); // 모든 스레드가 종료 될 때 까지 기다림 } long endMs = System.currentTimeMillis(); System.out.println( incrementInteger.getClass().getSimpleName() + ": ms=" + (endMs - startMs) + ", result=" + incrementInteger.get()); } } 결과 BasicInteger: ms=32, result=88652038 VolatileInteger: ms=3653, result=17721836 SyncInteger: ms=4882, result=100000000 MyAtomicInteger: ms=6953, result=100000000 MyAtomicInteger 보다 SyncInteger 가 성능이 좋은 이유는 CAS 는 기본적으로 락보다는 빠르지만, 경쟁이 심하면 CAS 실패로 재시도를 반복하기 때문에 성능이 락보다 안나오고 있는 것으로 보이네요.추가로 BasicInteger 에 비해서 VolatileInteger 의 손실율이 큰 이유는 모두가 동시에 메인 메모리에 접근하게 되면서 발생한 문제로 보이네요. 비유적으로 설명하면BasicInteger: 각자 수첩(캐시)에 메모하고 나중에 합침→ 충돌 적고, 결과는 꽤 괜찮음 (운이 좋으면)VolatileInteger: 100명이 하나의 화이트보드(메인 메모리)에 동시에 적으려는 상황→ 끊임없는 덮어쓰기, 충돌 많음 → 결과는 엉망 감사합니다. ^0^
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
sleep과 yield 차이점
이 둘을 이해하는데 조금 어려워서 차이점 질문 겸 이렇게 이해하고 있는게 맞는지 또는 이해해도 되는지 질문드립니다.sleep()과 ,yield() 공통점 : 둘 다 실행되면 다른 스레드에게 실행을 양보함 sleep()과 ,yield() 차이점sleep(ms) : 실행되면 주어진 시간동안 TIMED_WATING 상태가 된다. sleep이 실행된 스레드는 실행 스케쥴링에서 아예 빠진다. 따라서 해당 시간동안 전혀 실행되지 않는다.yield() : 호출되어도 계속해서 RUNNABLE 상태를 유지한다. yield()가 호출되면 해당 스레드는 sleep과 달리 스케쥴링에 대기상태로 들어간다. 이 말은 스케쥴링에 있기 때문에 다시 곧바로 실행 될 수 있다.예를들어 1000ms를 기준으로 비교하면 sleep()을 호출한 스레드는 1초동안 아무것도 못하지만, yield를 호출한 스레드는 1초동안 다른 얼마든지 곧바로 실행 될 수도 있고 몇번이든 실행 될 수 있다.이렇게 차이점을 이해했습니다. 이게 맞는지 이렇게 이해해도 되는지 궁금합니다 감사합니다.
-
해결됨앨런 Swift Concurrency for Swift 6 (Part-1)
비동기 반복문은 하나의 thread에서만 동작하게 되나요??
안녕하세요.강의를 통해 많은 도움을 받고 있습니다.!다름이 아니라, 17강 - 11분20초 부분에서 "작업의 결과를 모을 때는 하나의 thread에서만 동작하게 됩니다. 예를 들자면 2번 thread 하나에서만 비동기 반복문이 동작하게 되는거에요" 라고 설명을 해 주셨는데제가 이해한 바로는 'Swift Concurrency는 thread관점에서 벗어나서, Task라는 작업의 단위를 기준으로 비동기 관리를 한다' 라고 이해하고 있습니다.때문에, "비동기 반복문에서도 await을 통해 비동기 결과를 받고 있는데, 이 때 특정 thread에 고정된다는 것이 보장 될 수 있는건가?" 하는 궁금증이 생겨서 질문드립니다!만약 하나의 thread에 고정되어 있다면, group을 통해서 결과가 넘어오게 될 때, 자식 Task중 과도하게 오래걸리는 작업이 있다고 가정하면 비동기 반복문이 실행되는 특정 thread가 계속 blocking되는건가? 하는 의문이 들어서요,,,!
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
join 질문입니다.
thread1.join(); thread2.join();메인스레드 내에서 thread1,2를 join()을 하는데요.thread1.join()을 먼저 만났으니 메인 스레드는 thread1이 종료 될때까지 다음 코드를 실행하지 않을텐데요.여기서 메인스레드가 thread1의 결과를 기다리는 것이므로 thread1,2는 무관하게 그대로 번갈아가며 실행 되는 것이 맞나요? CPU((코어)가 1개라고 가정했을때요.그래서 메인은 thread1이 종료되고 결과를 기다릴뿐 thread1과 2의 종료 순서는 보장되지않는 것이 맞을까요?따라서 thread2가 먼저 작업을 끝낸 실행일 때도 있을 수 있겠죠? 단지 메인이 thrad1의 결과를 먼저 받으려고 기다릴뿐인거죠?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
notify(), notifyAll()
각각 3개로 한정된 소비자, 생산자 스레드가 있습니다. 생산자가 생산자를 깨운 것 처럼 notify()로 일어난 스레드가 다시 wait() 해야하는 경우 락을 반납하고 대기 상태에 든다면 이후 다시 notify()하는 스레드가 없기 때문에 교착상태가 발생하는건가요? (새롭게 추가되는 여러 스레드가 있다면 해결될 가능성도 있으나 새롭게 추가되지 않는 한정된 상황이라면 교착상태가 발생할 수 있으니 notifyAll() 사용이 올바른 선택인지 궁금합니다)
-
해결됨앨런 Swift Concurrency for Swift 6 (Part-2)
10강 내용 문의드립니다.
안녕하세요. 10강 내용 중 8분 40초 즈음에Task 가 여러 개일 경우 '동일 시점에 여러개의 쓰레드에서 접근/사용 가능성이 있기 때문에' Race Condition이 발생할 수 있다고 설명해주셨는데요. 교재 10p에서 'Task는 현재 실행중인 컨텍스트의 메타데이터를 그대로 상속해서 사용'한다고 설명하고 있고, 메타데이터에는 '실행 액터'도 포함되어 있어서(현재 시점에서는 액터를 쓰레드와 비슷한 의미로 이해하고 있습니다.) , Task 클로저 외부와 내부의 액터(~= 쓰레드?)는 같을 것 같은데요. 이로 미루어 봤을 때, Task 1과 Task 2의 클로저가 실행되는 쓰레드도 같아야 할 것 같다는 생각이 들더라구요.(swift 6모드에선 비동기 컨텍스트에서 Thread.current에 접근할 수 없어 swift 5 모드로 실행했습니다.)간단히 테스트 해봤을 때 위처럼 두개의 Task의 클로저가 실행되는 쓰레드가 메인 쓰레드로 같은데요. 이는 test() 메서드가 MainActor에서 실행되기에(@MainActor) 이와 같은 쓰레드에서 실행되는 것으로 이해했습니다.제가 잘못 이해하고 있는 지점이 있을 것 같은데요. 뒷 내용을 아직 듣지 못했지만 참지 못하고 질문드려봅니다! ㅎㅎ 답변해주시면 감사하겠습니다!
-
미해결파이썬 동시성 프로그래밍 : 데이터 수집부터 웹 개발까지 (feat. FastAPI, async, await)
AWS LighSail 접근 불가
AWS에 Free Tier로 가입했는데,LightSail에서 인스턴스 생성을 클릭하면 403 화면과 함께 아래 글이 뜹니다.제가 가입시 설정을 잘못 한건지, 최근에 무료로 lightsail 이용이 불가해진 건지 모르겠습니다.AWS에도 문의중인데, 여기에도 문의드립니다. Free account plan access limitationsFree account plans have limited access to certain services. If you are using a free account plan, you will need to upgrade to a paid account plan to access Lightsail. Learn more about how to upgrade your account plan
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
DataSource Hikari 사용 이유
DataSource 관련 질문이 있습니다!1. 왜 Hikari Pool을 사용하신건지 궁금합니다.2. Maximum Connection Pool Size를 40개로 설정하신 이유도 궁금합니다.
-
해결됨재고시스템으로 알아보는 동시성이슈 해결방법
saveAndFlush 사용 이유 문의
decrease 함수 안에서 일반적인 save가 아닌 saveAndFlush를 사용하는 이유가 궁금해서 문의 드립니다. 다른 이유가 있을까요?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
원자적 연산의 의미
원자적 연산의 의미가, i = 1;과 같이 한번의 수행으로 끝나는 동작이지만 넓은 의미에서는 일종의 트랜잭션처럼,여러 코드뭉치지만 하나의 연산으로 취급할 때에도 사용되나요? (강의 2:14참고)
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
join() 위치
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요 아직 끝까지 듣지 않았는데 궁금해서 질문 드립니다. volatile을 사용한 뒤에 메인에서 t1.start() 바로 뒤에 t1.join()이 오게 위치를 변경해주면 t1.start() 가 끝난뒤에 t2.start()가 시작이 되서 balance 값이 변경된 상태로 t2 스레드가 검증에서 false값이 걸리는줄 알았는데.. 이렇게 해도 문제가 발생하는데 그 이유가 궁금합니다.
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
volatile
안녕하세요 영한쌤!질문드립니다! 쓰레드별로 공유 자원에 대해 효율적인 연산 처리를 위해 캐시 메모리를 사용한다고 하셨습니다! 이러한 문제가 메모리 가시성 문제를 일으킬 수 있어 volatile 키워드로 캐시가 아닌 메인 메모리에 직접 접근할 수 있었습니다. 이번 예제의 경우,volatile이 없었던 가장 기본 BasicInteger는 volatile을 사용하지 않았어도 어느정도 값 수정이 되었는데 이는 캐시 메모리를 사용하지만 컨텍스트 스위칭이 발생하면서 캐시메모리가 메인메모리로 반영하고 다시 이를 읽어오니 반영이 된건가요?(이전에 interrupt를 boolean flag + volatile로 해결하던 예제에서는 컨텍스트 스위칭이 발생할 시기가 확정적이지 않다고 하셨는데 그거에 비해 꽤 많이 연산이 이뤄진것같습니다...)
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
스레드 실행 위치 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]섹션 5의 <프린터 예제3 - 인터럽트 코드 개선 관련> 질문입니다.printer.addJob(input) 관련하여, 어떤 스레드에서 어디서부터 어디까지 책임지고 실행하는지 헷갈려서 정리해봤는데 검토해주시면 감사하겠습니다. === printer.addJob(input) 은 main 스레드(호출 스택)에서 실행된다.공유하는 Heap 메모리 영역에 Printer 객체 주소가 있다.main 스레드는 Printer 객체의 jobQueue 변수에도 접근이 가능하고 addJob() 메서드를 호출할 수 있다.따라서, addJob() 메서드에 대한 스택 프레임도 main 스레드(호출 스택)에 쌓여서 처리된다. === JPA 이후 오랜 만에 영한님 강의를 다시 듣기 시작했는데 재밌네요. 늘 감사합니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
2:33초의 강의 내용
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]2:33초의 강의 내용 중 비효율이 있을 뿐 로직은 모두 정상 작동한다. 이 부분 말씀이 그냥 소비자가 소비자를 깨우는 상황에도 예를 들어 put(), take() 안의 로직이 작동한다는 거죠? 만약 생성자나 소비자가 같이 대기 하고 있을 때 같은 종류의 스레드만 계속해서 깨울 시에 starvation이 발생할 수 있는 것과는 이야기와는 별개인거 맞을까요?
-
해결됨앨런 Swift Concurrency for Swift 6 (Part-2)
강의를 들으면서 생긴 질문이 있습니다.
안녕하세요, 강의를 들으면서 생긴 질문 세가지가 있습니다. 답변해주시면 너무 감사드리겠습니다. Swift Concurrency에서 NSLock을 사용해도 되나요? 이전 GCD환경에서 데이터 동기화를 위해 사용하던 NSLock을 Swift Concurrency환경에서 사용해도 같은 효과를 볼수있을지 궁금합니다. Actor에 접근할때는 await으로 Task를 따서 비동기적으로 접근하는데, 기존에 비슷한 참조타입인 class에 접근하는것보다 속도가 느려지는 이슈는 없을까요? cpu에서 context switch를 하면, 저장하고 로딩하는 동기화하는 작업때문에 컨텍스트 스위칭이 비효율적이다 라고 설명해주셨는데, 그럼 swift concurrency에서는 task가 다른 cpu(다른 쓰레드) 에서 재개되는것도 동기화작업이 필요할텐데 이 작업은 비싼(?) 비효율적인 작업이 아닌가요? 질문이 조금 많은데.. 액터까지 강의 들으면서 궁금했던 점이라 부탁드립니다.
-
해결됨앨런 Swift Concurrency for Swift 6 (Part-2)
협력적 쓰레드 풀에서 쓰레드 운영방식 질문 드립니다.
3강 협력적 쓰레드 풀에서 쓰레드 운영방식에 대한 질문 드립니다.보통 컴퓨터 살때 8코어, 10코어..이런식으로 얘기 하잖아요..CPU당 하나의 쓰레드를 만들어서 운영한다면 Swift Concurrency에서는 8개, 10개 정도의 쓰레드만 가지고 동작하는건가요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
executor service를 스프링에서 이용한다면 어떻게 관리하는게 좋은가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]실무에서 강의를 수강하기 이전에 자바에서 제공하는 executor service를 사용하여 병렬로 프로그램을 짠 경험이 있는데요.저는 spring boot를 사용하여 service 내부에 executors의 고정스레드풀을 사용하여 특정 서비스를 호출할때마다 생성하도록 했습니다.예를 들면, List<?> methodA(req) { ExecutorService es = Executors.newFixedThreadPool(10); List<CompletableFutures> tasks ... // 비즈니스로직 finally{ // shutdown 로직}}공통으로 executor 서비스를 관리하는 클래스를 만들어서 사용해야할까요? 우선 제가 개발한 환경에서는 executor service를 저만 사용했습니다.만약 위에 제가 작성한대로 methodA를 호출할 때마다 쓰레드 풀이 생성되는거 같은데 맞을까요? 이런 방식보다 더 효율적으로 쓰레드를 관리하고 정리할 수 있는지 궁금합니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
tryLock 이후 InterruptedException 발생
락을 얻고 그 후에 InterruptedException이 발생 한다면 finally 에 unlock 을 작성 해 주어야 하나요 ?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
영한님, sleep(10) 이유가 궁금합니다.
안녕하세요. 영한님 궁금한 점이 있습니다.sleep(10) 를 하면 동시 실행을 더 촉진할 수 있다는 것이 이해가 안됩니다. 예를 들어, 아래를 가정한다면요! 각 시간은 별도로 가정한 것입니다. 1번 쓰레드가 1.0초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.1초에 실행 가정,2번 쓰레드가 1.1초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.2초에 실행 가정,3번 쓰레드가 1.2초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.3초에 실행 가정,... 그렇다면 각 쓰레드가 0.1초씩 쉬었다고 하더라도 결국에는 실행시점이1.1초, 1.2초, 1.3초 다 다르다고 봐도 되지 않나요?뭔가, sleep(10) 을 빠지게 되면 대부분 쓰레들이 비슷한 시점에 10ms 를 자고, 거의 동시에 깨어나서 increment() 를 실행하는 것 같은데 맞나요?맞다면 왜 그런가요? 감사합니다!