static은 클래스에 고정된다.
static멤버(static변수, static메서드) = 정적멤버
인스턴스에 소속되지 않고, 클래스에 고정되어 있다.
static 영역의 메모리에 저장되기 때문에 가비지 콜렉터의 관리 대상이 아니다.
테스트1. 두개의 instance에서 static 사용
plus, minus 메서드를 사용해서 static변수 `balance` 의 값이 어떻게 변하는지 관찰
단일 스레드에서 실행
// application 실행
@Slf4j
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
StaticTestService instance1 = new StaticTestService();
log.info("plus 30,000 : {}", instance1.plus(30000));
log.info("minus 5,000 : {}", instance1.minus(5000));
StaticTestService instance2 = new StaticTestService();
log.info("instance2 balance : {}", instance2.getBalance());
/**
* 결과
* plus 30,000 : 30000
* minus 5,000 : 25000
* instance2 balance : 25000
*/
}
}
@Service
public class StaticTestService {
private static int balance = 0;
public int getBalance() {
return balance;
}
public int plus(int value) {
balance += value;
return getBalance();
}
public int minus(int value) {
balance -= value;
return getBalance();
}
}
멀티스레드에서도 static 변수
테스트2. plus, minus API 호출시 static 변수의 상태
- spring boot 기본 멀티 스레드 사용 (controller로 api호출)
- 여러번의 호출에도 `balance` 값이 계속 유지되는지 관찰
@Slf4j
@RestController
public class StaticTestController {
StaticTestService service = new StaticTestService();
@GetMapping(value = "/balance")
public int getBalance(){
return service.getBalance();
}
@GetMapping(value = "/plus/1000")
public int plus1000(){
int balance = service.plus(1000);
log.info("[service id : {}] plus 1,000 : {}", StaticTestService.id , balance);
return balance;
}
@GetMapping(value = "/minus/500")
public int minus500(){
int balance = service.minus(500);
log.info("[service id : {}] minus 500 : {}", StaticTestService.id , balance);
return balance;
}
}
/**
* 결과
* service instance가 계속 새로 생성되지만 balance는 유지된다. (instance uuid로 확인)
* 서버가 재시작되고, application이 초기화되면 balance도 초기화 된다.
*/
/**
* log
* 2022-01-02 16:23:14.348 INFO 45661 --- [nio-8081-exec-7] c.g.s.controller.StaticTestController : [service id : e786bf2d-339b-4627-bda6-ad3d6115ec48] plus 1,000 : 1000
* 2022-01-02 16:23:15.092 INFO 45661 --- [nio-8081-exec-8] c.g.s.controller.StaticTestController : [service id : e786bf2d-339b-4627-bda6-ad3d6115ec48] plus 1,000 : 2000
* 2022-01-02 16:23:17.271 INFO 45661 --- [nio-8081-exec-9] c.g.s.controller.StaticTestController : [service id : e786bf2d-339b-4627-bda6-ad3d6115ec48] minus 500 : 1500
* 2022-01-02 16:23:22.132 INFO 45661 --- [io-8081-exec-10] c.g.s.controller.StaticTestController : [service id : e786bf2d-339b-4627-bda6-ad3d6115ec48] plus 1,000 : 2500
* 2022-01-02 16:23:24.612 INFO 45661 --- [nio-8081-exec-1] c.g.s.controller.StaticTestController : [service id : e786bf2d-339b-4627-bda6-ad3d6115ec48] minus 500 : 2000
*
* 서버 재시작 후, uuid 변경
* 2022-01-02 16:25:37.904 INFO 45689 --- [nio-8081-exec-2] c.g.s.controller.StaticTestController : [service id : af378220-6177-4606-813e-562caac4752d] plus 1,000 : 1000
* 2022-01-02 16:25:38.620 INFO 45689 --- [nio-8081-exec-3] c.g.s.controller.StaticTestController : [service id : af378220-6177-4606-813e-562caac4752d] plus 1,000 : 2000
* 2022-01-02 16:25:40.720 INFO 45689 --- [nio-8081-exec-4] c.g.s.controller.StaticTestController : [service id : af378220-6177-4606-813e-562caac4752d] minus 500 : 1500
*/
@Service
public class StaticTestService {
private static int balance = 0;
public static final UUID id = UUID.randomUUID();
public int getBalance() {
return balance;
}
public int plus(int value) {
balance += value;
return getBalance();
}
public int minus(int value) {
balance -= value;
return getBalance();
}
}
'Back > Java' 카테고리의 다른 글
[Java/Reactor] Mono then() 동작 흐름 테스트 (0) | 2023.02.22 |
---|---|
[Spring/WebSocket] 초초초기본편 웹소켓 통신해보기 (1) (0) | 2022.09.18 |
[Spring/WebSocket] RSocket 예제코드 실행해보기(WIP) (1) | 2022.09.15 |
[JPA] save() vs saveAndFlush() 차이 (0) | 2021.11.26 |
[Spring/mybatis] null check (0) | 2021.01.22 |