묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
yield()를 추가해도 무한반복은 계속해서 발생하지 않을까요?
안녕하세요. 강의 수강 중 궁금한 것이 있어 질문드립니다.MyPrinterV4에서 yield()를 추가해도 인터럽트 되지 않은 상태에서 while문에서 무한 반복이 발생(성능저하의 근본 원인)하는 것은 V3와 동일하기 때문에 때문에 성능 향상이 있을까 싶습니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
trylock(1500)질문입니다
안녕하세요 강의 잘보고 있습니다. 강의 내용중 tryLock메서드 실습 부분에 서 tryLock에 인자로 500 밀리초를 넘겨 0.5초동안 락을 획득하지못하면 포기하는 것을 실습했습니다. 추가로 1500밀리초를 넘겨서 돌려봤는데 이때도 락을 얻지 못했습니다. 출금시간은 1초라서 락해제까지 완료가 된상태인데 왜 다음스레드가 락을 얻지 못할까여,, ㅠㅠ19:00:56.252 [ Thread-1] 거래 시작: BankAccountV519:00:56.252 [ Thread-0] 거래 시작: BankAccountV519:00:56.254 [ Thread-1] [검증 시작] 출금액: 800, 잔액: 100019:00:56.254 [ Thread-1] [검증 완료] 출금액: 800, 잔액: 100019:00:56.752 [ main] t1 state: TIMED_WAITING19:00:56.752 [ main] t2 state: TIMED_WAITING19:00:57.258 [ Thread-1] [출금 완료] 출금액: 800, 잔액: 20019:00:57.258 [ Thread-1] Thread-1 락 해제19:00:57.258 [ Thread-1] 거래 종료19:00:57.758 [ Thread-0] [진입 실패] 이미 처리중인 작업이 있습니다 if (!lock.tryLock(1500, TimeUnit.MILLISECONDS)) { log("[진입 실패] 이미 처리중인 작업이 있습니다") return false } lock.lock() //그냐 트라이랑 세트라 보삼 try { log("[검증 시작] 출금액: $amount, 잔액: $balance") if (amount > balance) { log("[검증 실패] 출금액: $amount, 잔액: $balance") return false } log("[검증 완료] 출금액: $amount, 잔액: $balance") Thread.sleep(1000) balance -= amount log("[출금 완료] 출금액: $amount, 잔액: $balance") } finally { log("${Thread.currentThread().name} 락 해제") lock.unlock() //언락 반드시 해야함 }코드가 코틀린인점 죄송합니다.. 자바랑 같은라이브러리를 사용해서 혹시나해서 여쭤봅니다
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
비공정 모드가 공정 모드가 빠른 이유
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]비공정 모드가 공정 모드가 빠른 이유가 뭔지 자세히 궁금합니다. 비공정 모드에서도 어느 정도 대기큐가 있다고 하셨는데 그 걸 제외하고 공정 모드에서는 대기큐를 사용하면 어떤 스레드가 다음 락을 가져야할 지 알기 때문에 좀 더 빠르지 않나? 라는 생각이 들어서요.. 그리고 비공정 모드에서는 반대로 대기큐를 사용하지 않았기 때문에 공정 모드보다 락 얻기 위한 경합이 일어나서 좀 더 느릴 수 있는거 아닌가..? 싶어서 여쭤봅니다..시스템 상황에서 어떻게 비공정 모드가 공정 모드보다 빠른지 이해가 가지 않네요..ㅠㅠ
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
실무에서 excutor service사용
안녕하세요. 실무에서 시간이 오래소요되는 3개의 delete쿼리를 excutor service를 사용하여 멀티스레드형식으로 1개의 스레드가 1개의 쿼리를 수행하도록 구현해보고 싶습니다. 그런데 멀티스레드를 사용했을때 트랜잭션은 보통 어떻게 처리하시나요.. ? 저는 @transactional 을 선언해서 사용하고 있는데 이는 스레드1개당 트랙잭션이 생성되는거라 제가 의도한데로 롤백이 제대로 안될거라고 하더라구요.. 3개의 쿼리가 모두 성공했을때 커밋되고 그렇지않으면 롤백시키고싶은데 이부분에 대한 지식도 혹시 알수있을까요? 추가로 혹시 해당 질문 관련 강의를 개설해놓으신게 있다면 알려주시면 감사하겠습니다!
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
네임드락과 분산락
네임드락에 대해 더 공부해보려고 구글링하는데네임드락이 MySQL에서 제공하는 분산락이라고 하더라구요 그럼 네임드락이 여러 개로 스케일 아웃된 DB 환경 혹은 스케일 아웃된 서버에서도 잘 동작한다는건데전자의 경우 (DB 분산) 네임드락도 결국 쿼리로 하나의 데이터베이스(MySQL)의 메타데이터에 락을 거는 것이기 때문에 다른 데이터베이스에서는 그게 안걸려 정합성 문제 해결이 안되지 않나요? 이렇게 되면 분산락이 아닌 것 같은데 왜 분산락일까요?ㅜㅜ후자의 경우라면 비관적락, 낙관적락, 네임드락 모두 잘 동작할 것 같은데(데이터베이스는 하나인 경우) 왜 분산락이라는게 따로 있는 걸까요..?
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
facade 패턴 질문
현재 진행중인 프로젝트에 Aop 구현은 힘들어서 facade를 통해 Redisson lock을 적용해보려고 합니다.facade 패턴을 처음 접해서 그런지 프로젝트에 어떻게 적용해야 할지 고민입니다.service 로직을 건들지 않고, facade 패턴을 사용해서 역할분리 한 거에 대해서는 이해했습니다만,mvc 패턴에서, controller가 결국 동시성 제어가 적용된 서비스를 이용하려면 service(createReservation)가 아니라 facade(createReservation)를 사용해야 하는데, controller가 service로도 동시성 제어가 적용되지 않은(사용해서는 안될) 메서드(createReservation)에 접근이 가능하다는 점에서 문제가 될수도 있다고 생각했습니다.(비슷한 상황으로 컨트롤러가 reposiotry를 가끔 참조하기도 하는데, 이때의 경우는 service에 굳이 해당 로직을 만들지 않을때인데, 지금 같은 경우는 비슷한 로직이 service에도 있고, facade 에도 있는 경우라.. ) 협업에서 어떤 개발자의 실수로 service 계층의 createReservation(사용해서는 안될)가져다 쓸 수 있다는 것이 신경쓸 문제가 아닌지, 아니면 컨트롤러가 그 서비스의 메서드에 접근을 못하게 한다던지, 실제로 어떻게 적용하시는지 궁금합니다.
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
Redisson lock() vs tryLock()
반드시 실행 되어야할 서비스 로직에 lock(3,TimeUnit.SECONDS) 이럭식으로 사용하려고 하는데 tryLock() 대신 써도 될지 궁금합니다.코드 찾아보면, 다들 tryLock() 쓰시던데,시스템적으로 저렇게 계속 lock획득 대기 상태로 만들어 놓으면, 안되는건지 궁금합니다.lock 대기 상태일때도 커넥션이 잡혀있나요?lock 대기상태가 많아지면 서버가 다운될 수 있나요?
-
해결됨김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
unlock()에 synchronized를 걸면 왜 무한루프를 도는지가 이해가 안됩니다..ㅠㅠ
synchronized를 unlock에 걸 필요가 없다는건 이해를 했는데 이것 저것 실험(?)을 해보다가 unlock()에 synchronized를 걸면 무한 대기 상태가 지속되는지 이해가 안됩니다..ㅠㅠ제가 계속 고민을 한 로직으로는 Thread-1이 비즈니스 로직을 실행한 후 finally를 실행해서 락을 반납해 Thread-2가 어느 정도 시간이 지난 후에 락을 받아서 실행이 될 것이라고 생각을 했는데 아니라서 많은 고민 끝에 질문을 남겨봅니다..ㅠㅠ 답변 기다리겠습니다..!
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
future.get()
public static void main(String[] args) throws InterruptedException, ExecutionException { SumTask task1 = new SumTask(1, 50); SumTask task2 = new SumTask(51, 100); ExecutorService es = Executors.newFixedThreadPool(2); Future<Integer> future1 = es.submit(task1); Future<Integer> future2 = es.submit(task2); log("작업 시작"); long st = System.currentTimeMillis(); Integer sum1 = future1.get(); long end = System.currentTimeMillis(); log(end - st + "ms"); Integer sum2 = future2.get(); log("task1.result = " + sum1); log("task2.result = " + sum2); int sumAll = sum1 + sum2; log("task1 + task2 = " + sumAll); es.close(); }02:45:32.785 [ main] 작업 시작 02:45:32.785 [pool-1-thread-1] 작업 시작 02:45:32.785 [pool-1-thread-2] 작업 시작 02:45:34.794 [pool-1-thread-1] 작업 완료 result = 1275 02:45:34.794 [pool-1-thread-2] 작업 완료 result = 3775 02:45:34.797 [ main] 2007ms 02:45:34.797 [ main] task1.result = 1275 02:45:34.797 [ main] task2.result = 3775 02:45:34.797 [ main] task1 + task2 = 5050 맨 위 코드를 실행했을 때 위와 같은 출력이 나왔습니다.main 메서드는 BlockingQueue에 등록된 future를 스레드 풀에서 가용 가능한 스레드 만큼 모두 실행 시킨 후에 WAITING 상태로 변경된다고 이해하면 될까요?
-
미해결김영한의 실전 자바 - 고급 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에서 프록시에 대한 설명이 있는데요, 제가 알고 있는 데코레이터 패턴과 완전히 동일한 거 같은데 둘간의 차이점은 뭐라고 봐야하나요?
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
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