static의 사용 이유와 스레드(thread)의 대한 개념
1. JVM의 메모리 구조
JVM의 메모리 구조에는 여러 영역이 있지만 static, stack, heap 영역 3가지 공간에 대한 정리를 하려고 합니다.
구체적인 JVM의 메모리 구조에 대한 정리는 링크를 참고해주시면 될 것 같습니다.
JVM의 구조를 간단하게 정리하자면 다음과 같습니다.
- JVM의 메모리 구조는 Stack, Heap, Static 영역이 존재한다.
- Stack 영역에는 '스택 프레임'라는 용어를 사용하는데 '{'를 만나면 생성되고 '}'를 만나면 사라지게 된다.
- 기본형 타입 변수의 값들과 Heap 영역에 존재하는 인스턴스를 참조하는 참조값 변수들은 스택 영역에 존재한다.
- Heap 영역에는 인스턴스가 저장되어 있고 스택영역에 해당 인스턴스를 참조하는 변수들을 이용해 인스턴스를 제어할 수 있다.
- Static 영역에는 static 이 붙는 변수, 메서드가 저장된다.
여기서 우리는 static 영역에 대한 정리를 해보려고 합니다.
1. static
static으로 선언된 메서드나 멤버변수들은 static 영역에 생성되면서 모든 객체 들이 사용할 수 있는 공유 개념을 가집니다.
public class Practice {
private static int value;
static {
value = 100;
}
public static void main(String [] args ) {
System.out.println(value);
}
}
static의 특징은 다음과 같습니다.
- 객체를 생성하지 않고도 사용가능하다.
- 모든 객체가 공유하는 변수가 된다.
정리하자면, static은 공간을 공유한다는 것입니다. 이 static 공간을 공유해서 사용하는 주체가 스레드(thread)입니다.
2. 스레드(thread) 란?
스레드는 '프로세스 내에서 실제로 작업을 수행하는 단위'를 의미합니다.
예를 들자면, '재고 관리' 프로그램에서 여러 사용자가 동시에 접속할 수 있으며, 이 프로그램은 A 상품이라는 단일 재고를 관리합니다. 각 사용자는 프로그램에 접속하여 재고를 추가하거나 삭제할 수 있는 기능을 수행할 수 있습니다.
A 사용자, B 사용자, C 사용자가 일정한 시간을 두고 동시에 프로그램에 접속한다고 가정해 보겠습니다. 각 사용자가 접속하면 프로그램 내에서 각 사용자를 위한 스레드가 생성됩니다. 즉, 각 사용자마다 독립적인 스레드가 생성되어 자신의 작업을 수행하게 됩니다.
이렇게 각 프로세스 내에서 여러 스레드가 생성됨으로써, 사용자들은 동시에 재고 관리 작업을 수행할 수 있습니다.
3. static을 사용하는 이유는 무엇일까?
이전의 예시에서, 이때, '6시' 이후에는 해당 프로세스에 접속하지 못하게 하고, 이미 접속 중인 사용자는 강제로 종료하도록 하는 상황을 추가하겠습니다.
이 상황을 관리하기 위해 '접속 제한 시간'이라는 변수를 사용할 수 있습니다. 이 변수는 프로그램 전반에 걸쳐 공유되어야 하므로 static으로 관리하는 것이 효과적입니다. 이유는, static 변수를 사용하면, '6시'에서 '7시'로 변경해야 할 경우, static 변수만 수정하면 되기 때문에 유지보수가 용이합니다. static 변수는 클래스 수준에서 공유되는 변수로, 모든 인스턴스가 동일한 값을 공유합니다. 이를 통해 효율적으로 특정 값을 관리할 수 있다는 특징이 있습니다.
4. static을 사용의 주의사항
static을 적절한 목적을 두고 사용한다면 프로그램을 유지보수하는데 큰 효과를 줄 수 있지만 반대로 적절히 사용하지 못한다면 오히려 프로그램 상의 오류가 존재할 수 있습니다. 예를 들어 보겠습니다.
A, B, C 3명의 사용자가 5초의 시간 간격을 두고 접속 중이고 하나의 프로세스가 종료되는 데 까지는 100초의 사긴이 걸린다고 가정해 보겠습니다. 재고는 100개가 있다고 가정해 보겠습니다.
C가 프로그램이 실행된 지 10초의 시간이 흘렀다면 B는 15초, A는 20초가 흘렀을 겁니다. 이때 각 프로그램 시작 30초가 지날 때 A는 재고 20개를 가져가고 B는 재고 30개를 가져가고 C는 재고 30개를 추가한다고 가정해 보겠습니다. 그럼 각각의 결과는 80, 50, 80 개의 재고가 보여져야 합니다.
하지만 static변수로 선언됐기 때문에 프로세스가 다 종료되기 전에 static변수를 수정하는 일이 발생하기 때문에 세 프로그램이 모두 종료 됐을 때 각각의 결과가 모두 80개로 동일한 결과가 나오는 불상사가 생기게 됩니다. 이러한 이유는 static이 가지고 있는 '공간을 공유' 한다는 특징 때문입니다.