묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
스레드 기아상태 - 모든 스레드가 wait인 상황
안녕하세요 영한님바로 아래 질문에서 조금 더 의문이 있어 질문드립니다.4분대 그림에서 c0 소비자 스레드는 데이터를 얻고 notify()해서 스레드 대기 집합에 있는 임의의 스레드를 깨울 것입니다.만일 이때 소비자 스레드 c1이 깨어나면, 큐에 소비할 데이터가 없어서 다시 스레드 대기 집합으로 들어갈텐데, 그 다음은 notify()를 호출할 스레드가 없어서 모든 스레드가 WAITING 상태로 대기 집합에 있을 것으로 생각합니다. 그러면 이후 다른 새로 생성된 생산자 스레드가 put()을 호출하지 않는한 모든 스레드가 쉬고 있는 상황에 놓이는게 맞을까요? 결국에는 p1을 깨우지 않는 스레드 기아 상태는 이해되는데,교안에 "최악의 경우 c1 ~ c5 스레드가 반복해서 깨어날 수 있다." 표현에서 스레드들이 계속 연쇄적으로 깨어나는 뉘앙스가 느껴져서 명확히 하고자 여쭤봅니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
오타 제보드려요!
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]교안 "8. 생산자 소비자 문제 1" - 12 page - 3번째 줄"임계 영역은 synchronized를 영역을 뜻한다."-> "임계 영역은 synchronized를 적용한 영역을 뜻한다.""적용한"이 빠져서 다음 업데이트 때 반영되면 좋을 것 같아 남깁니다.좋은 강의 항상 감사드립니다 영한님! :)
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
분산락과 서버별 락에 대해 질문드립니다!
안녕하세요 영한님!다중서버로 이루어진 분산환경에서 분산락이 주로 사용되는데 이는 전체 또는 여러 서버에서 동기화가 필요한 데이터여서 그런것이죠? 현재 학습내용인 자바에서 제공하는 락 (서버별로 락을 갖는 방식은) 분산환경에는 적합하지 않고,서버별로 락을 걸어도 커버 되는 자원에 한정되게 사용되는걸로 이해한게 맞을까요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
프록시 패턴 vs 데코레이터 패턴
섹션11에서 프록시에 대한 설명이 있는데요, 제가 알고 있는 데코레이터 패턴과 완전히 동일한 거 같은데 둘간의 차이점은 뭐라고 봐야하나요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
q를 입력하면 예외가 발생하는데 그 이유를 모르겠습니다.
안녕하세요. 항상 강의 잘 듣고 있습니다 🙂public static void main(String[] args) throws InterruptedException { Printer printer = new Printer(); Thread printerThread = new Thread(printer, "printer"); printerThread.start(); Scanner sc = new Scanner(System.in); while (true) { log("프린터할 문서를 입력하세요. 종료 (q): "); String str = sc.nextLine(); if (str.equals("q")) { printerThread.interrupt(); break; } printer.addJob(str); } } static class Printer implements Runnable { Queue<String> jobQueue = new ConcurrentLinkedQueue<>(); @Override public void run() { log("outer 상태 : " + Thread.currentThread().isInterrupted()); while(!Thread.interrupted()) { try { if (jobQueue.isEmpty()) { continue; } String job = jobQueue.poll(); log("출력 시작: " + job + ", 대기 문서: " + jobQueue); log("inner 상태 : " + Thread.currentThread().isInterrupted()); Thread.sleep(3000); log("출력 완료"); } catch (InterruptedException e) { e.printStackTrace(); log("인터럽트!"); System.out.println(e.getMessage()); break; } } log("프린터 종료"); } public void addJob(String str) { jobQueue.offer(str); } }저는 q를 입력하면 인터럽트 상태가 false로 바뀌게 되고, 프린터 종료 로그가 남을 거라고 생각했습니다.실행하고 바로 q를 입력하면 제가 예상한 대로 동작하지만, 값을 입력 후 q를 입력하면Thread.sleep(3000);이 부분에서 InterruptedException 예외가 발생했습니다.저는 이 부분에서 의문점이 들었습니다.while(!Thread.interrupted()1. 인터럽트 상태가 바뀌었을 텐데 왜 예외가 발생하지?2. 상태가 안 바뀌었나?라는 생각을 하고 로그를 확인해봤는데07:21:21.366 [ printer] outer 상태 : false 07:21:21.366 [ main] 프린터할 문서를 입력하세요. 종료 (q): 123 07:21:22.790 [ main] 프린터할 문서를 입력하세요. 종료 (q): 07:21:22.796 [ printer] 출력 시작: 123, 대기 문서: [] 07:21:22.796 [ printer] inner 상태 : false q java.lang.InterruptedException: sleep interrupted at java.base/java.lang.Thread.sleepNanos0(Native Method) at java.base/java.lang.Thread.sleepNanos(Thread.java:491) at java.base/java.lang.Thread.sleep(Thread.java:522) at thread.control.printer.MyPrinterV3$Printer.run(MyPrinterV3.java:46) at java.base/java.lang.Thread.run(Thread.java:1570) 07:21:22.980 [ printer] 인터럽트! sleep interrupted 07:21:22.980 [ printer] 프린터 종료q를 입력하면 바로 예외가 발생해서 상태가 바뀌었는지는 잘 모르겠습니다.만약 상태가 안 변했다고 해도 결국 sleep 부분에서 예외가 발생할 텐데, 로그가 안 찍힌 이유도 모르겠습니다.그래서 여러 번 실행해본 결과 값 입력하고 3초 후 q를 입력하면 예외가 발생하지 않는다는 걸 알게 되었습니다.잠자고 있는 스레드를 깨워서 문제가 발생하는 것 같은데 제 지식으로는 여기까지인 것 같습니다.질문 1. while(!Thread.interrupted()) 이 부분에서 인터럽트 상태가 false로 변경되었을 것 같은데 예외가 발생한 이유를 모르겠습니다. 제가 다시 생각해보니 프린터 스레드는 sleep() 때문에 3초 기다리고 있는 상태에서 깨우니 sleep() 부분에서 예외가 발생하고 로그도 안 찍혔을 것 같다는 생각이 들었습니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
오타 제보합니다
사소한 부분이긴 하지만 오타 제보합니다.synchronized vs ReentrantLock 대기 파트의 ReentrantLock 의 대기2: await() 대기 부분에서 WAITING 상대로 대기 -> WAITING 상태로 대기로 수정이 필요할 것 같습니다.감사합니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
모든 스레드가 wait 상태
강의 4분대 그림에서 c0가 queue 가 비어서 wait 상태로 들어가면 notify를 호출하지 않기때문에 모든 스레드가 wait 상태에 들어가지 않나요? while문을 벗어나야 notify를 호출할 수 있잖아요. 어떻게 되는지 궁금합니다.
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
[생산자 소비자 문제2] Lock(ReentrantLcok) 강의 화면의 이미지와 강의 자료가 다르게 나와 있습니다.
강의에서는, ReentrantLock 의 대기 큐까지 포함된 이미지로 설명을 하시는데, 강의 자료에서는, 대기 큐가 빠진 상태로 나와 있습니다. [강의 화면] [강의 자료]S
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
오타
자바 고급19. 생산자 소비자 문제2 (8~9page)BoundedQueueV5 영상내용과 문서 불일치 합니다.put, take 메소드 내부 문장이try ~ finally (영상기준)try ~ catch ~finally(문서기준)영상이 맞는 거 같네요.검토 바랍니다.
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
getter메소드에 락관리
3:05에서 getBalance()에서 계속 동시성 관리를 하는 이유가 메모리가시화 문제 때문인가요? 만약 그런거라면 앞으로 멀티스레드환경에 노출된 인스턴스변수들은 단순 반환만하는 getter메소드에서도 무조건 volitile이나 락관리를 해야되는게 맞을까요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
LockSupport.park()의 isInterrupted() 질문
안녕하세요. 김영한님의 강의 잘 보고 있습니다.바보 같은 질문일 수 있지만, Thread.sleep()과는 다르게 LockSupport.park()는 interrupt()를 이용해서 깨어나도 isInterrupted()가 true인 이유가 궁금합니다.그냥 단순히 InterruptedException이 발생하지 않기 때문일까요?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
this 질문
그러면 main 메소드 내에Thread thread1 = new Thread(..);Thread thread2 = new Thread(..); 이걸 실행하면main 스택프레임내에 참조변수가 저장이될텐데thread1,thread2가 아닌 this로 저장된다는건가요? 그러면 예를들어, 참조변수 a의 메소드를 실행하게된다면 먼저 스택프레임내에서 참조변수에서 실제 인스턴스가 저장된 힙 주소를 꺼내어서 그 힙주소로 간다음 메소드를 가져오는게 아니라 참조변수 a가 아닌 this 인거죠?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
스레드와 메모리영역 질문
1:31 경에 쓰레드1,2,3 3개의 객체를 만들고 실행하잖아요 그러면 1:49 그림에서 3개의 인스턴스가 그려져야하는거 아닌가요?반복문을 통해 Thread를 100개 실행하고 있습니다. 여기서, thread 참조변수에 Thread 객체를 생성하고 있던데, 그렇다면 for문 순회하나하고 블록 종료시점에 스택프레임이 제거되어 thread 참조변수는 제거될것이고 힙영역에 Thread 객체가 존재하다가 나중에 GC 실행시점에 Thread 객체가 지워질것으로 보이는데 맞나요? 만약 그렇게 Thread 객체가 지워진다면 실행중이던 스레드도 중단되나요?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
메서드 영역에 static 변수?
자바 8부터 Heap 영역에 Static Object(Static Variable, static객체 , static method)이 존재하고MetaSpace에는 static reference만 저장한다고 아래 글에서 읽었습니다.https://openjdk.org/jeps/122어떤게 맞는건가요? 제가 오역한거같지는 않은게 다른 분들도 그렇게 말씀하시는것 같습니다.https://jgrammer.tistory.com/entry/JAVA-Java8%EB%B6%80%ED%84%B0%EB%8A%94-static%EC%9D%B4-heap%EC%98%81%EC%97%AD%EC%97%90-%EC%A0%80%EC%9E%A5%EB%90%9C%EB%8B%A4
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
동적 의존성 주입과 Volatile
[질문]2024.08.07 까지는 정액할인, 2024.08.08 부터는 비율할인 정책이 반영되어야 하는 비즈니스 로직이 있고, 이를 스케줄러를 활용하여 2024.08.08 00:00:00에 Setter를 활용하여 비율할인을 구현한 Bean을 Injection 하여 처리하도록 구현했다고 가정하면, 이런 경우에도 아주 아주 엄밀하게 00:00:00에 모든 할인 정책이 완벽히 적용되어야 한다면, 인스턴스 변수에 volatile을 반드시 명시해줘야 하는 것인가요? 경험이 미천하여 웹프로그래밍 할 때 volatile를 사용한 것을 거의 보지 못하였고, 위의 가정처럼 아주 엄밀한 동작을 요구하는 경우는 없었고 그간 별다른 일도 없긴 하였는데, 개념을 듣고 복기해보니 장애의 요인이 될 수 있을 것 같아 여쭙습니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
6. synchronized 문제 1 log출력
public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); Runnable task = new Runnable() { @Override public void run() { for (int i = 0; i < 10000; i++) { counter.increment(); log(counter.getCount()); // 로그 출력 추가!!!!!!!!!!!!!!! } } }; Thread thread1 = new Thread(task); Thread thread2 = new Thread(task); thread1.start(); thread2.start(); thread1.join(); thread2.join(); log(counter.getCount()); } static class Counter { private int count; public void increment() { count++; } public int getCount() { return count; } } 문제를 푸는 도중 count의 값을 확인해보고 싶어서 MyLogger.log(counter.getCount());를 호출했더니 문제 없이 20000이 계속 출력됩니다.synchronized를 사용하지 않아서 여전히 동시성 문제는 발생할텐데 어떻게 20000이라는 값이 나오게 되는지 궁금합니다!!
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
Runnable 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]https://javatrainingschool.com/multithreading/thread-lifecycle/위 링크에서는 Runnable과 Running 상태를 분리하는데 혹시 두개의 차이가 있나요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
스레드 대기 집합 질문
여기에서 스래드 대기 집합은 WAITING, TIMED_WAITING, BLOCKED가 보관되는 곳과는 다른 큐를 의미하는게 맞을까요?
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
Blocked 되지 않는 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]쓰레드의 동시성이슈를 syncronized로 해결하였을때로그를 보면, 00:53:11.012 [ t1] 거래 시작: BankAccountV300:53:11.012 [ t2] 거래 시작: BankAccountV300:53:11.020 [ t1] [검증 시작] 출금액: 800, 잔액: 100000:53:11.021 [ t1] [검증 완료] 출금액:800, 잔액: 100000:53:11.489 [ main] t1 state: TIMED_WAITING00:53:11.490 [ main] t2 state: TIMED_WAITING00:53:12.021 [ t1] [출금 완료] 출금액:800, 잔액: 20000:53:12.021 [ t1] 거래 종료00:53:12.021 [ t2] [검증 시작] 출금액: 800, 잔액: 20000:53:12.022 [ t2] [검증 실패]00:53:12.024 [ main] 최종 잔액: 200이런식으로 t1, t2 두 쓰레드중 하나가 blocked 되는 것이 아니라 모두 time_waiting상태로 유지 됩니다.뭔가 느낌으로는 큰 상관은 없을 것 같고, 시스템 환경에 따른 차이인 거 같은데, 혹시나 제가 세팅을 잘못했거나 코드를 잘못 짰을 가능성도 있을까요.## 메인 클래스를 반복해서 실행해보니t1, t2 스레드 모두 time waiting 상태이거나 모두 blocked 상태가 됩니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
원자적 연산을 확실히 알수 있는 방법이 있나요?
i++ 은 1줄이지만 , 2~3개의 cpu 연산이 필요하므로 원자적 연산이 아닙니다.cas 도 상식적으로는 2개 이상의 cpu 연산이 필요한데 cpu 차원에서 1개의 cpu 연산처럼 제공해주기에, 원자적 연산이라고 보는것 같습니다.아래와 같은 경우 원자적연산인데,int count = 3; 그렇다면 아래의 코드는 원자적연산인가? 생각해보면, max 값을 가져오고 그걸 대입해야 하므로 2개 이상 cpu 연산이 필요한것 같은데 확신은 들지 않습니다.int count = max; --그래서... 어디까지가 원자적 연산인지 확실히 알수 있는 방법이나 이와 관련된 스펙문서 등이 있는지 궁금합니다.