JAVA 스터디 3주차

이봐요이상해씨·2021년 9월 11일

JAVA

목록 보기
3/6

ex1

  • static 키워드란?

    메모리에 한번 할당되어 프로그램이 종료될 때까지 해제되는 것을 의미

  • static 변수

    특징

    • static 변수는 클래스 변수이다

    • 객체를 생성하지 않고도 static 지원에 접근이 가능하다.

      초기화시점

    • JVM에 의해서 클래스가 메모리 공간에 올라가는 순간

  • static 메서드

    특징

    • 객체 생성없이 호출 가능

    • static 메서드로 접근하기 위해선 static 변수로 선언되어야 함

      스태틱 변수와 스태틱 메서드는 스태틱 메모리 영역에 존재함으로 객체가 생성되기 이전 이미 할당되어있는 상태 → 객체의 생성없이 바로 접근하여 사용할 수 있다

  • 클래스 변수(static 변수)

    클래스 전체와 연결된 필드

    static 클래스 변수

    • 같은 클래스의 객체들이 다루는 데이터를 저장하는 변수
    • 생성한 각 객체들이 서로 값을 공유
    • 인스턴스 변수에 static만 붙여주면됨
  • 클래스 메서드(static method)

    인스턴스 메서드와 달리 인스턴스를 생성하지 않아도 클래스 메서드를 호출할 수 있다

  • static 변수는 언제 생성되는가?

    • static 변수와 static 메서드는 메모리 영역에 존재함
    • 객체가 생성되기 이전 이미 할당 ⇒ 객체 생성없이 바로 사용 가능
  • 참고사이트

설명 :

  1. 테스트케이스에서 studentname과 studentid를 직접 호출함으로public으로 변수 선언
  2. serialnum은 여러개의 인스턴스가 하나의 값을 공유할 필요함으로 static으로 선언
  3. static은 데이터 영역 메모리에 생성됨(일반 인스턴스는 힙 메모리에 생성되는 반면)
  4. 따라서 인스턴스 생성과 상관없이 사용 가능
  5. static 변수를 위해 static method로 생성함

ex2

  • singleton pattern

    싱글톤 패턴이란?

    • 인스턴스가 오직 1개만 생성되어야 하는 경우 사용됨
    • 동시성 문제 고려해야 함
    • 하나의 인스턴스를 메모리에 등록하여 여러 스레드가 동시 공유 사용
    • private constructor를 갖고 static method를 사용
  • 싱글톤 패턴 종류

    • 이른 초기화(Eager Initialization)

      public class Singleton {
          // Eager Initialization
          private static Singleton uniqueInstance = new Singleton();
      
          private Singleton() {}
      
          public static Singleton getInstance() {
            return uniqueInstance; 
          } 
      }
      • 클래스 로더가 초기화 되는 시점에서 정적바인딩을 통해 인스턴스에 메모리 등록
      • 클래스가 최초 로딩시 객체 생성 → 스레드 세이프함
      • 스레드 세이프 →멀티 스레딩 환경에서 동작 가능하게금 구현
    • 늦은 초기화 동기화 불럭(Lazy Initialization with synchronized)

      public class Singleton {
          private static Singleton uniqueInstance;
      
          private Singleton() {}
      
          // Lazy Initailization
          public static synchronzied Singleton getInstance() {
            if(uniqueInstance == null) {
               uniqueInstance = new Singleton();
            }
            return uniqueInstance;
          }
      }
      • 컴파일이아닌 인스턴스 필요시점 요청시 초기화, 인스턴스 생성
      • 무조건 동기화 불록 생성 → 성능 하락
    • DCL(Lazy Initialization. Double Checking Locking)

      public class Singleton {
          private volatile static Singleton uniqueInstance;
      
          private Sigleton() {}
      
          // Lazy Initialization. DCL
          public Singleton getInstance() {
            if(uniqueInstance == null) {
               synchronized(Singleton.class) {
                  if(uniqueInstance == null) {
                     uniqueInstance = new Singleton(); 
                  }
               }
            }
            return uniqueInstance;
          }
      }
      • 위의 방법 개선, 인스턴스가 생성되지 않은 경우만 동기화 불럭 실행

      • volatile이란?

        main memory에 값을 저장하고 읽어오기 때문에 읽고 쓰기시 변수값 불일치가 생기지 않음(캐시에 쓰지 않음)

    • 열거 상수 클래스(Lazy Initailization. Enum)

      public enum Singleton {
          INSTANCE; 
      }
    • 게으른 홀더(Lazy Initialization. LazyHolder)

      public class Singleton {
      
          private Singleton() {}
      
          /**
           * static member class
           * 내부클래스에서 static변수를 선언해야하는 경우 static 내부 클래스를 선언해야만 한다.
           * static 멤버, 특히 static 메서드에서 사용될 목적으로 선언
           */
          private static class InnerInstanceClazz() {
              // 클래스 로딩 시점에서 생성
              private static final Singleton uniqueInstance = new Singleton();
          }
      
          public static Singleton getInstance() {
              return InnerInstanceClazz.instance;
          }
          
      }
      • getInstance()메서드 호출시 초기화
      • 동적바인딩 특징 이용
  • 객체의 유일성

  • 참고 사이트

    자바 싱글톤 패턴 (Singleton Pattern)

    싱글턴 패턴(Singleton Pattern)

설명

  1. 싱글톤은 한 클래스에 인스턴스가 하나만 존재하게 구현하는 것을 말하는 패턴 = 어떤 클래스가 최초 한번만 메모리를 할당하고, 그 매모리에 객체를 만들어 사용하는 디자인 패턴

private static CardCompany company = new CardCompany();

private static으로 자기자신의 클래스를 인스턴스로 갖고 있게함

  1. 고전적인 싱글톤 패턴 구현

    1. 싱글톤 패턴 만들때 주의점은 생성자를 private으로 만들고 클래스 내부에 인스턴스를 생성함 그리고 해당 인스턴스를 전역으로 사용하게끔 static 메소드를 제공(생성자가 private임으로 new나 외부에서 접근이 불가능하다) 그리고 static으로 선언함으로 메모리에 유일 객체 생성하게끔함
    2. 단점 : 멀티 스레드 환경 대비 못함
    3. if문에서 thread A 에서 thread B로 제어권 넘어감 thread B가 인스턴스 생성함 그리고 다시 제어권이 thread A로 넘어감으로서 인스턴스가 또 생성됨(이사이에서 컨텍스트 스위칭이 일어날 경우)

    컨텍스트 스위칭 : cpu가 어떤 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다음 우선순위의 프로세스가 실행되야할때 기존 프로세스 상태나 값(레지스트)를 저장하고 다음 프로세스 수행하기 위해 새로운 프로세스 상태나 값으로 교체하는 작업

    컨텍스트 스위칭

[[JAVA 디자인패턴] Singleton 패턴의 모든 것 (멀티스레드 고려)](https://javaplant.tistory.com/21)
  1. synchronized를 통한 싱글톤 패턴

    1. synchronized 키워드는 단일 쓰레드가 대상 메소드를 호출~종료까지 다른 쓰레드 접근 lock함 따라서 고전적인 싱글톤패턴의 중복생성문제 해결
    2. 단점 : 인스턴스 리턴마다 thread 동기화 때문에 불필요한 lock이 걸림 → 비용낭비

    쓰레드 동기화 : 여러개의 쓰레드가 한개의 자원사용시 해당 쓰레드만 제외하고 나머지 접근을 막는 것을 말함

  2. DCL(Double-Checked-Locking) Singleton 패턴

    1. synchronized의 경우 인스턴스 할당 시점만 처리되면 해결될 문제를 전체 getInstance() 에 synchronized 처리해서 성능문제발생 이를 해결하는 패턴

    2. getInstance()내부에서 instance를 생성하는 경우만 부분적으로 synchronized 처리

      → 인스턴스가 생성되어있는지 확인하고 없는 경우 lock 시킨후 인스턴스 생성

    c. 단점 → 멀티스레드 작업시 메인메모리가 아닌 cpu cache에 변수값을 저장함.

    그런데 멀티 스레드환경에서 스레드가 변수값 읽어올때 cpu 캐쉬에서 저장된 값이 다르기 때문에 변수값 불일치로 문제가 발생할 수 있음

    d. 그래서 volatile 키워드를 사용, volatile 은 cpu캐시가 아닌 메인 메모리에서 변수를 참조 함 따라서 불일치 문제가 생기지 않음

    스태틱 메소드 안의 동기화 블록

    다음 예제는 스태틱 메소드에 대한 것이다. 두 메소드는 각 메소드를 가지고 있는 클래스 객체를 동기화 기준으로 잡는다.

    같은 시점에 오직 한 쓰레드만 이 두 메소드 중 어느 쪽이든 실행 가능하다. 두 번째 동기화 블록의 괄호에 MyClass.class 가 아닌 다른 객체를 전달한다면, 쓰레드는 동시에 각 메소드를 실행할 수 있다.

    자바 동기화 블록(Java Synchronized Blocks)

  3. LazyHolder Singleton 패턴

    1. static 영역을 초기화 하지만, 필요한 시점까지 초기화 미룸
    2. 클래스 변수가 없어 클래스 로딩시 초기화가 안됨(Company 클래스)
    3. getInstance() 메서드에서 InnerCompany Instance 참조시 클래스 로딩되며 초기화 진행
    4. final로 선언한 인스턴스 객체는 단한번 생성되고 이후 다시 인스턴스가 할당되는것을 막음(final 객체 선언시)
    5. 클래스 내부의 클래스는 외부 클래스가 초기화 될때 초기화 되지 않고 클래스의 static변수는 클래스를 로딩할 때 초기화되는 것을 이용한 기법 → 클래스 로딩, 초기화는 JVM영역

    https://coding-factory.tistory.com/525

    Lazy Initialization. LazyHolder(게으른 홀더, Thread-safe)

    LazyHolder 방식은 가장 많이 사용되는 싱글턴 구현 방식입니다.

    volatile 이나 synchronized 키워드 없이도 동시성 문제를 해결하기 때문에 성능이 뛰어납니다.

    싱글턴 클래스에는 InnerInstanceClazz 클래스의 변수가 없기 때문에, static 멤버 클래스더라도, 클래스 로더가 초기화 과정을 진행할때 InnerInstanceClazz 메서드를 초기화 하지 않고, getInstance() 메서드를 호출할때 초기화 됩니다. 즉, 동적바인딩(Dynamic Binding) (런타임시에 성격이 결정) 의 특징을 이용하여 Thread-safe 하면서 성능이 뛰어납니다.

    InnerInstanceClazz 내부 인스턴스는 static 이기 때문에 클래스 로딩 시점에 한번만 호출된다는 점을 이용한것이며, final을 써서 다시 값이 할당되지 않도록 합니다.

ex3

  • 지역변수
  • 인스턴스변수
  • static변수
  • scope와 life cycle
  • 생성되는 메모리
  • 소멸시점

설명

  1. 하나의 company에서 여러개의 카드가 생성되는 경우이다. 즉 company 인스턴스는 하나만 존재해야 함으로 싱글톤으로 생성
  2. 여러개의 카드 발급시 발급번호에 ++ 되어서 생성됨으로 serailNum은

ex4

  • 객체의 배열 사용하기

    • 기본 자료형인 int arr = new int[10]; 과 다르게 객체를 담는 배열이다
    • 생성자를 통해 만드는 인스턴스를 담는 배열
    • System.arraycopy(얕은복사)d
      • 앞에서부터 (복사할 배열, 복사를 시작할 위치, 붙여넣기할 배열, 붙여넣기할 위치, 복사하는 길이)를 뜻함
  • 얕은복사

    • 주소값만을 복사
    • 원본 내용이 바뀌면 주소값 복사한 카피본도 내용 바뀜
    • arraycopy를 사용
  • 깊은복사

    • 주소가 아닌 원본값을 카피본에 직접 대입하는 복사
    • 새로운 객체를 new로 생성해서 직접 복사해주어야함
  • 출처

    자바(java) 배열의 깊은 복사(deep copy)와 얕은 복사 완벽정리(1차원 배열, 2차원 배열, 객체 배열 복사)

ex5

  • ArrayList클래스 메서드

    • List 인터페이스를 상속받은 클래스

    • 가변적으로 변하는 선형리스트

    • 저장용량이 늘어나면 가변적으로 증가

    • ArrayLIst list = new ArrayList();

  • javaDoc

  • enhanced for문

    for 문으로 배열의 요소의 처음부터 끝까지 모든 요소 참조

    for(변수 : 배열){
    }
  • 출처

    [자바 ] ArrayList에 여러 값 담기](https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rbdi3222&logNo=220699749409)

0개의 댓글