묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
lock.tryLock(15, 1, TimeUnit.SECONDS) 질문입니다!
안녕하세요! 강의를 보면서 많은 도움 얻고있습니다.항상 감사합니다! 궁금한점이 아래 시간에 해당하는 부분인데요.boolean available = lock.tryLock(15, 1, TimeUnit.SECONDS);강사님과 저의 테스트코드에선 thread를 100개를 만들어 놓고 테스트를 진행했습니다.그리고 락을 한번 획득하면 1초동안 점유하고 있고, 락 획득을 위해 대기할 수 있는 시간은 총 15초 입니다.그래서 락을 획득할 수 있는 스레드는 1초에 한개씩으로, 테스트코드가 성공하려면 총 100초가 걸려야 하고, 지금 상황으로는 성공하지 않아야 정상이라고 생각하는데 강사님의 코드에서 성공한 이유가 뭔지 궁금합니다!제가 아직 이해를 제대로 못해서 뭔가를 놓친 것 같은데 감이 잘 안잡히네요 ㅠㅠ
-
미해결김영한의 실전 자바 - 고급 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() 부분에서 예외가 발생하고 로그도 안 찍혔을 것 같다는 생각이 들었습니다.
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
레디스 질문
레디스 재고처리 강의가 많은 도움이 되었습니다. 그러다 궁금한것이 있습니다.Q. 사이드 프로젝트로 쇼핑몰을 만드려고 합니다프론트: 리액트 벡엔드 api서버: 스프링부트2.8api서버에 레디스를 연결해 최근 검색어 캐싱 + 구매에 의한 재고 감소 동시성 처리를 하려고 합니다. 이때 벡엔드 api 서버(스프링부트)에 레디스를 연결하는게 맞나요 아니면 별도의 서버를 하나 더 구축해 레디스를 연결하는게 맞나요?? 사이드 프로젝트인 상황에 맞게 어떻게 하는게 바람직한지 궁금합니다
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
오타 제보합니다
사소한 부분이긴 하지만 오타 제보합니다.synchronized vs ReentrantLock 대기 파트의 ReentrantLock 의 대기2: await() 대기 부분에서 WAITING 상대로 대기 -> WAITING 상태로 대기로 수정이 필요할 것 같습니다.감사합니다.
-
미해결운영체제 공룡책 강의
java 소켓 통신 예제 질문
DateClient 클래스에서 소켓을 생성하면서 ip address와 포트 번호를 넘겨줄 때, 127.0.0.1 대신 cmd 창에서 ipconfig 명령어로 확인한 IPV4 주소를 입력하면 정상적으로 작동하지 않는데, 왜 그런 건지 궁금합니다. ipconfig에 나오는 주소값도 자신의 ip주소를 가리키는 게 아닌가요?
-
미해결김영한의 실전 자바 - 고급 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 상태를 분리하는데 혹시 두개의 차이가 있나요?
-
해결됨자바 동시성 프로그래밍 [리액티브 프로그래밍 Part.1]
[공유] setName 시 threadName이 1부터 시작하는 이유
해당 강의 10분 경 나온 설명으로, setName 메소드 자체가 스레드 이름에 영향을 주나? 싶은 궁금증이 들어서 확인해 보았고, 저와 비슷한 궁금증을 가지신 분들이 계실 것 같아 공유드립니다. setName은 Thread name 생성 로직에는 관여하지 않습니다. 다만, 해당 예제에서는 new Thread()로 이름 없는 스레드를 생성 후(이 때 Thread-0으로 생성), 해당 Thread를 setName을 통해 Thread name을 바꿔주고 있어서, setName을 사용하면 1부터 카운트되는 것 처럼 보였던 것입니다. -> 새로 생성된 스레드의 이름은 Thread-0-> Thread-0이 yourThread로 치환됨 yourThread를 생성하는 부분에서 Thread의 이름을 임의로 넣어주고, 아래에서 스레드를 생성하면 0번부터 생성됨을 확인할 수 있습니다.
-
미해결김영한의 실전 자바 - 고급 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; --그래서... 어디까지가 원자적 연산인지 확실히 알수 있는 방법이나 이와 관련된 스펙문서 등이 있는지 궁금합니다.