본문 바로가기

Java59

스레드 동기화를 위한 volatile, Atomic volatile 하나의 변수를 여러 스레드에서 사용할 때 사용하는 키워드로 변수를 CPU 캐시가 아닌 Main Memory에서 변수의 값을 읽거나 저장하겠다라는 것을 명시하는 것이다. 즉, volatile은 CPU Cache에 저장된 값을 읽는 것 보다는 성능이 안좋지만 컴파일러에게 해당 데이터(변수, 메서드)에 대해 멀티스레드로 접근하고 있음을 알려주어 읽기, 쓰기에 대해서 동기화를 보장하여 예측불허하게 바뀌는 것을 막을 수 있다. synchronized와의 차이는 다음과 같다. synchronized: 행위(메서드 및 블럭)에 대한 동기화 volatile: 행위의 타겟(변수)에 대한 동기화 volatile을 사용하는 이유는 Main Memory의 값을 읽고 저장해 가시성을 보장하기 위한 것이라고 할 .. 2023. 7. 22.
Thread 클래스(with synchronized) Thread 우리가 JVM을 실행시키면 자바 프로세스(Java Process)가 시작한다. 이 프로세스에는 여러 개의 스레드가 수행되는데 반대로 여러 프로세스가 공유하는 하나의 스레드가 수행되는 일은 절대 없다. 어떤 프로세스든 간에 스레드가 하나 이상 수행된다. 프로세스(Process): 운영체제로부터 시스템 자원을 할당받아 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체) 스레드(Thread): 프로세스가 할당받은 자원을 이용하는 실행의 단위 이 때, Java Thread는 일반 스레드와 거의 차이가 없으며, JVM이 운영체제의 역할을 한다. 즉, Java Thread는 JVM에 의해 스케되는 실행 단위 코드 블록이라고 할 수 있고, 스레드 스케줄링 및 스레드와 관련된 많은 정보들을 .. 2023. 7. 22.
GC(Garbage Collection), GC는 어떻게 대상 선정할까? Garbage Collection(가비지 컬렉션) 프로그램을 개발하다 보면 유효하지 않은 메모리인 가비지(Garbage)가 발생하게 된다. C언어를 이용하면 free()라는 함수를 통해 직접 메모리를 해제해주어야 하지만 Java나 JavaScript을 이용해 개발을 하다보면 개발자가 메모리를 직접 해제해주는 일은 없다. 그 이유는 JVM의 Garbage Collector가 프로그램이 동적으로 할당했던 메모리 영역 중 불필요한 메모리를 알아서 정리(해제)해주기 때문이다. 여기서 동적으로 할당했던 메모리 영역은 프로그램 런타임에 사용되는 Heap 메모리 영역을 뜻하고, 불필요한 영역은 어떤 변수도 가리키지 않게 된 영역을 의미한다. 장점 이렇게 GC를 도입하면 수동으로 메모리를 관리하던 것에서 비롯된 에러들.. 2023. 7. 17.
Java의 소수점 계산 오류 및 해결 소수점 계산 public class Calculate { public static void main(String[] args) { System.out.println(0.1 + 0.2); // 0.30000000000000004 } } console.log(0.1 + 0.2); // 0.30000000000000004 프로그래밍에서 소수점 계산은 흔한 일이다. 우리 실생활에서 소수점을 계산해야 하는 경우가 많고, 달러로 계산할 때에도 소수점 계산은 흔히 사용된다. 그 때 만약 0.1 + 0.2와 같은 소수점 계산에서 0.30000000000000004로 결과가 나와 계산이 틀리게 되면 큰 문제가 발생할 수도 있다. 왜 0.1 + 0.2 계산에서 0.3이 아닌 0.30000000000000004이 나왔을까?.. 2023. 7. 16.
ArrayList와 LinkedList 차이 List List Interface(리스트 인터페이스)는 대표적인 선형 자료구조로 주로 순서가 있는 데이터를 목록으로 이용할 수 있도록 만들어진 인터페이스다. 우리가 배열을 사용할 때 int[] array = new int[10];처럼 사용하지만 이러한 경우는 10개의 공간 외에는 더이상 사용하지 못한다. 만약 array[13] = 30;가 실행되면 할당된 크기(범위) 밖이기 때문에 IndexOutofBoundsException라는 에러가 발생한다. 이러한 단점을 보완하여 List를 통해 구현된 클래스들은 '동적 크기'를 갖으며 배열처럼 사용할 수 있게 되어있다. 한 마디로 배열의 기능 + 동적 크기 할당이 합쳐져 있다고 보면 된다. List Interface에 선언된 대표적인 메서드 메서드 리턴 타입 .. 2023. 7. 15.
Java의 hashCode, equals와 hashCode 같이 써야하는 이유 Hashing은 컴퓨터 과학에서 핵심정인 개념 중 하나이다. 자바에서 효율적인 해시 알고리즘은 HashMap 및 HashSet와 같은 잘 사용하는 컬렉션들의 밑바탕이 되는 개념입니다. 여기서는 hashCode가 동작하는 방식, 어떻게 컬력션에 기여하는지, 올바르게 구현하는 방법에 대해 알아보자. 아래는 Hash와 관련된 게시글 링크이다. Hash란? Java로 Hash Table 구현하기 Hash Java의 hashCode 메서드를 공부하던 중 깊이있게 이해하기 위해서는 먼저 Hash에 대해 이해할 필요성을 느끼고 Hash에 대해서 먼저 정리해보기로 한다. 그러면 Hash란 무엇일까? Hash는 key와 value가 oneny.tistory.com hashCode Java에서 사용되는 해시코드(Hashc.. 2023. 7. 10.
String Literal vs new String 이전 게시글에서 String은 immutable한 객체로 immutable한 객체를 다른 변수에 할당하는 경우에 Heap 메모리에 존재하는 값을 공유하는 것이 아닌 복사하여 복사한 값을 가리킨다고 설명했다. 이런 immutable한 String 객체에 대해서 좀 더 자세히 살펴보자. 그리고 아래는 이전 게시글 링크이다. JVM의 Stack&Heap 이해하기 JVM은 이런 OS의 메모리 영역에 접근을 해서 Java의 메모리를 관리하는 가상 프로그램을 의미한다. 이 메모리를 그냥 사용해서는 안되고 누군가 쓸 때 할당을 해주고 또 다쓰고 나면 해제를 해줘야 oneny.tistory.com String Literal vs new String public class StringTest { public static.. 2023. 7. 9.
JVM의 Stack&Heap 이해하기 JVM은 OS의 메모리 영역에 접근을 해서 Java의 메모리를 관리하는 가상 프로그램을 의미한다. 이 메모리를 그냥 사용해서는 안되고 누군가 쓸 때 할당을 해주고 또 다쓰고 나면 해제를 해줘야 한다. 메모리 관리를 C나 C++을 개발할 때는 사용자가 직접 관리를 해줘야 했지만 자바에서는 GC가 직접 해준다. 이러한 JVM의 Stack과 Heap 영역에 대해서 자세히 살펴보자. JVM Java의 Stack과 Heap에 대해서 이해하기 위해서는 먼저 JVM에 대한 이해가 필요하다. 간단하게 자바에서 메모리 관리가 어떻게 이루어지는지 살펴보자. JVM 이전 C/C++ 문제점 위 그림처럼 리눅스에서 컴파일해서 나온 실행파일을 윈도우에서 돌리게 되면 안돌아간다. C/C++는 컴파일 플랫폼과 타겟 플랫폼(= 운영체.. 2023. 7. 8.
빈 생명주기(라이프사이클)와 빈 스코프 빈 생명주기 스프링 빈은 간단하게 다음과 같은 라이프사이클을 가진다. 객체 생성 -> 의존관계 주입 스프링 빈 객체를 생성하고, 의존관계 주입이 다 끝난 다음에야 필요한 데이터를 사용할 수 있는 준비가 완료된다. 따라서 초기화 작업은 의존관계 주입이 모두 완료되고 난 다음에 호출해야 한다. 스프링 빈의 이벤트 라이프사이클 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료 데이터베이스 커넥션 풀이나 네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요하다. 이에 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백.. 2023. 7. 3.