
스코프와 프록시import jakarta.annotation.PostConstruct;import jakarta.annotation.PreDestroy;import org.springframework.context.annotation.Scope;import org.springframework.context.annotation.ScopedProxyMode;import org.springframework.stereotype.Component;import java.util.UUID;@Component//@Scope(value = "request")@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)public class MyLogger { ..
ObjectProviderObjectProvider 를 공부하다가 의문이 생겨 정리할 겸 글을 작성한다.아래의 코드는 prototype Bean 옵션을 사용하고 있다.PrototypeBean 클래스를 사용하여 주입받는ClientBean 이 있다. package hello.core.scope;import jakarta.annotation.PostConstruct;import jakarta.annotation.PreDestroy;import jakarta.inject.Provider;import org.assertj.core.api.Assertions;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.ObjectProvide..
@Configuration 먼저 각각의 빈들은 @Configuration이 있든 없든 싱글톤으로 유지된다. @Configuration 어노테이션을 사용하지 않고@Bean으로만 사용한다면, 스프링 컨테이너에는 등록이 되지만SpringCGLIB 클래스가 자식으로 등록이 되지 않아 대부분의 싱글톤 기능을 모두 잃게 된다. 무슨 의미일까? 아래를 참고해보자.@Configurationpublic class AppConfig { @Bean public MemberService memberService() { System.out.println("call AppConfig.memberService"); return new MemberServiceImpl(memberRepository..

동시성 컬렉션동시성 컬렉션이 필요한 이유package thread.collection.simple.list;public interface SimpleList { int size(); void add(Object e); Object get(int index);}package thread.collection.simple.list;import java.util.Arrays;import static util.ThreadUtils.sleep;public class BasicList implements SimpleList { private static final int DEFAULT_CAPACITY = 5; private Object[] elementData; private int ..
원자적 연산아래의 코드는 단순히 값을 하나 증가 시키는 코드이다.멀티스레드 환경이라면 synchronized나 Lock 같은 안전한 임계 영역을 설정해주어야 한다.value++; 와 같은 연산은 원자적 연산이 아니라, 3단계에 걸친 연산이 진행되기 때문이다.package thread.cas.increment;public class BasicInteger implements IncrementInteger{ private int value; @Override public void increment() { value++; } @Override public int get() { return value; }}package thread.cas.incre..

생산자 소비자 문제package thread.bounded;import util.MyLogger;import java.util.ArrayList;import java.util.List;import static util.MyLogger.log;import static util.ThreadUtils.sleep;public class BoundedMain { public static void main(String[] args) { // 1. BoundedQueue 선택 BoundedQueue queue = new BoundedQueueV4(2); // 2. 생산자, 소비자 실행 순서 선택, 반드시 하나만 선택! //producerFirst(queue); ..
synchronized의 가장 큰 단점인 무한 대기 문제를 LockSupport로 해결할 수 있다.LockSupport1LockSupportimport util.MyLogger;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.LockSupport;import static util.MyLogger.log;import static util.ThreadUtils.sleep;public class LockSupportMainV1 { public static void main(String[] args) { Thread thread1 = new Thread(new ParkTest(), "Thread-1"); ..
Synchronizedsynchronized 메서드import static util.MyLogger.log;import static util.ThreadUtils.sleep;public class BankAccountV2 implements BankAccount { private int balance; public BankAccountV2(int initialBalance) { this.balance = initialBalance; } @Override public synchronized boolean withdraw(int amount) { log("거래 시작: " + getClass().getSimpleName()); // 잔고가 출금액..