Singleton - LazyHolder

Singleton - LazyHolder

소프트웨어 디자인 패턴에서 싱글턴 패턴을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다

 

Singleton 구현방법

 

  1. 기본적인 Singleton 구현방법 (Thread-Safe)

getInstance method 로 인스턴스로 가져올때 마다 synchronized 키워드로 인해 동기화 과정에서 Lock으로 인한 성능 저하가 생길 수 있음

이리하여 DLC(Double-Checked-Locking) Singleton 으로 진화하게 됨

 

  1. DLC(Double-Checked-Locking) Singleton

DLC Singleton과 같은 경우는 멀티쓰레드 환경에서 컴파일러에 따라 재배치(reordering)문제를 야기할 수도 있다는데,

어느 블로그가 정리한 내용을 빌려오자면

소스코드가 논리적으로 문제가 없지만 컴파일러에 따라서 재배치(reordergin)문제를 야기한다.

위에 소스가 컴파일 되는 경우 인스턴스 생성은 아래와 같은 과정을 거치게 된다.

멀티쓰레드 환경일 경우 각 스레드마다 동일 메모리를 공유하는 것이 아닌 별도 메모리 공간에서 변수를 읽어온다. 이런 경우 각 스레드마다 동일한 변수의 값을 다르게 기억할 수 있다. 만약 Thread A가 인스턴스 생성을 위해서 instance = some_place;를 수행하는 순간 Thread B가 Test.getInstace()를 호출하게 되면 아직 실제로 인스턴스가 생성되지 않았지만, Thread B는 instance == null 의 결과가 false로 리턴되어 문제를 야기하게 된다.

 

  1. Initialization on demand holder idiom (holder에 의한 초기화)

개발자가 직접 동기화 문제에 대해 코드를 작성하고 문제를 회피하려 한다면 프로그램 구조가 그 만큼 복잡해지고 비용 문제가 생길 수 있고 특히 정확하지 못한 경우가 많다.(100%가 아닐수 있음)

그런데 이 방법은 JVM의 클래스 초기화 과정에서 보장되는 원자적 특성을 이용하여 싱글턴의 초기화 문제에 대한 책임을 JVM에 떠넘긴다.

holder안에 선언된 instance가 static이기 때문에 클래스 로딩시점에 한번만 호출될 것이며 final을 사용해 다시 값이 할당되지 않도록 만든 방법.

가장 많이 사용하고 일반적인 Singleton 클래스 사용 방법이다.

 

'Java' 카테고리의 다른 글

2. 객체지향 언어 특징  (0) 2018.07.26
1. Java란  (0) 2018.07.26
2. 변수자료형연산자  (0) 2017.03.16
1. 기본 입출력  (0) 2017.03.16
2.객체지향 언어 특징

객체지향 언어(Object Orientied Language) 특징

1. 캡슐화

짧게 정리하면 데이터(정보)와 데이터를 다루는 방법(메소드)를 결합시켜 묶는 것.

이는 더욱 깊게 들어가면 코드를 재수정 없이 재활용 하는 방법이라고 설명 할 수 있다.

프로그램 코드를 재활용 하려고 하는데 기능(함수/프로시저 : 메소드)이 분산되어 있고 특성(변수 : 데이터)이 분산 되어 있는 프로그램 코드는 재활용을 하기 매우 힘들다. 이 때문에 관련 기능과 특성을 한곳으로 모으고 분류할 필요성이 있다.

  • 클래스 & 인스턴스

객체 지향에서는 이렇게 계층적으로 분류한 기능과 특성의 모음을 클래스(Class)라는 캡슐(capsule)에 분류된 집단 별로 각각 집어 넣는다. 이러한 클래스를 실체화(Instance) 하면 객체(Object)를 만들수 있다.

붕어빵 틀 = 클래스

붕어빵 = 객체(인스턴스)

2. 상속

사실 클래스 이전의 프로그래밍 기법에선 코드 재활용이 불가능하지는 않았다. 예전에도 라이브러리 등을 통해서 남이 짜놓은 코드를 그대로 가져올 수 있었다.

  • '라이브러리'의 문제점

라이브러리는 코드의 재활용에 지대한 영향을 미쳤지만 치명적인 단점이 있었다. 라이브러리의 기능을 약간 바꾸어야 할 경우 라이브러리의 소스를 변경해야 했고 이 때문에 전혀 다른 라이브러리가 되어 버린다는 것이다. 이것은 라이브러리 버전에 따라 그 라이브러리를 사용하는 프로그램이 동작을 안할수도 있다는 것이고 불필요한 코드의 수정작업을 해야 한다는 것이다.

  • '상속'의 도입

객체 지향 프로그램에서는 이 문제를 해결하기 위해 "상속"을 도입 했다."포용성"으로 이전의 라이브러리보다 더 논리적이고 체계적으로 기능과 데이터를 계층적으로 분류해서 사용의 편의성을 도모하면서, 상속을 사용해 부모 클래스의 특성과 기능을 그대로 이어받고 기능의 일부분을 변경해야 할 경우 상속 받은 자식 클래스에서 그 기능만을 다시 정의하여 수정하게 하였다. 이러한 작업을 "덮어쓰기(재정의 : Override)"라고 한다.

 

3. 다형성

하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것을 말한다. 위에서 설명한 오버라이딩 이외에, 변수에 따라 함수의 기능이 달라지는 오버로딩도 여기에 해당한다.

  • 연산자 오버로딩

C++, C# 등에서는 기본 연산자를 오버로딩해서 기본 연산자가 해당 클래스에 맞는 역할을 수행하게 하는 것도 가능하다. JAVA 등에서는 연산자의 오버로딩이 불가능하다. 펄 6나 스몰토크, F# 등, 연산자의 신규 정의가 가능한 언어도 있다.

 

 

 

'Java' 카테고리의 다른 글

싱글톤 (Singleton)  (0) 2020.08.19
1. Java란  (0) 2018.07.26
2. 변수자료형연산자  (0) 2017.03.16
1. 기본 입출력  (0) 2017.03.16
1.Java란

JAVA

자바(Java)를 짧게 설명하자면 우리 제임스 고슬링 형님께서 가전 제품내에 동작하는 프로그램을 만드는 용도로 개발하신 객체지향언어 이다.

 

객체 지향 프로그래밍(Object Oriented Programming), OOP

프로그램 을 어떻게 설계해야 하는지에 대한 일종의 개념이자 방법론

 

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체'라는 기본 단위로 나누고 이 객체들의 상호작용으로 서술하는 방식

 

기존 절차적 프로그래밍에서는 메소드를 기계, 데이터를 원료로 생각해서 데이터가 메소드 사이를 통과하면서 차츰 순서대로 가공돼 나가는 방식으로 이해한다면 객체 지향 프로그래밍에서는 데이터를 중심으로 메소드가 데이터에 접근해서 수정한다는 개념이다. 즉 원료가 움직이냐 기계(함수, 메소드)가 움직이냐의 차이.

 

절차적 프로그래밍 vs 객체 지향 프로그래밍

 절차 지향 언어객체 지향 언어
장점1. 완성된 코드의 실행처리 속도가 빠르다.
2. 초기 프로그래밍 언어로 컴퓨터의 구조와 비슷해 속도가 빠르다.
1. 코드 재사용 용이
2. 코딩이 간단
3. 유지보수가 쉽다.
4. 대형 프로젝트에 좋다.
단점1. 유지보수가 어렵다.
2. 분석이 어렵다.
3. 대형 프로젝트에 부적합
1.처리속도가 상대적으로 느림
2.객체가 많으면 용량이 커질 수 있다.
3.설계 시 많은 시간이 투자 된다.
4. 설계 실패 시 처음부터 다시 시작

출처 : http://hunit.tistory.com/151

그럼 같은 객체 지향 언어인 c++ 과 차이점이 뭘까?

c++은 c언어의 로우 레벨의 시스템 프로그래밍의 강점 + 객체 지향 언어의 하이 레벨 기능들을 포함

Java는 포인터라는 강력한 무기를 포기하는 대신, 객체 지향(oop)에 집중하여 언어적 완성도를 높임

 

C++ vs JAVA 비교

1.상속

c++는 다중 상속 지원, Java는 다중 상속 지원x

다중 상속을 할 때, 다이아몬드 문제가 발생하는데, c++은 이를 회피할 수 있는 기능을 제공(virtual)

 

다이아몬드 문제

다중 상속을 하면 일어나는 문제가 있는데 그것은 다이아몬드 문제가 발생한다.

만약 A가 print()라는 메소드가 있다고 가정하자. 그럼 B와 C도 print() 라는 메소드를 보유하고 있을 것이다..

이 때 D의 인스턴스를 만들고, print() 메소드를 사용 할 경우, 모호(ambiguous)가 발생하며 메소드를 수행하지 못할 것이다.

이는 B가 상속받은 A의 메소드인지 , C가 상속받은 A의 메소드의 것을 사용하는지 모호하기 때문이다.

그래서 virtual키워드를 통해 A의 print() 메소드를 명시해 주어 모호하지 않게 해주는 것이다.

 

1.2 friend 키워드

c++은 friend 키워드 지원, Java는 지원 x

예를 들어 A클래스가 B클래스를 friend키워드를 통해 명시하면, A가 private로 데이터 또는 메소드를 접근제어자로 명시해도 B는 접근이 가능하다.

 

1.3 Interface

Java는 다중 상속이 없는대신, Interface를 통해 흉내낼 수 있다. 또 한 Interface는 상속이 아닌 구현이기 때문에

모든 추상 메소드를 구현 해야만 하기 때문에 다이아몬드 문제가 발생하지 않는다.

 

참고로, Interface는 상수와 추상 메소드로만 이루어짐.

 

2. 메모리 처리

앞서 JVM에 대해 소개했듯, JAVA와 C++의 메모리 처리(이런 '용어'를 써도 되는지 모르겠다.)에도 차이가 있는데...

첫째로, JAVA는 객체를 메모리의 Heap영역에만 할당할 수 있으나, C++의 경우 Heap과 Stack영역 모두에 할당이 가능하다. C++에서 new 키워드를 통해 객체를 생성하면 Heap영역에 객체가 할당되고, 일반적인 변수 선언 방식을 택하면 Stack영역에 할당이 된다. JAVA에서는 일반적인 변수 선언 방식으로 객체를 생성할 수 없다. (http://preamtree.tistory.com/28 [스크랩자료]Heap과 Stack의 비교)

둘째로, JAVA는 메모리(Heap 영역) 해제가 자동으로 이루어지지만, C++은 프로그래머가 수동으로 해야한다. JAVA에서는 Garbage Collector가 미사용 객체 등의 자원을 자동으로 해제하며, 프로그래머는 수동으로 GC를 조작할 수 없다. C++에서는 Destructor(소멸자)를 통해 메모리 해제가 가능하다.

 

3. 문법 및 기능

첫째로, C++에서는 연산자오버로딩을 지원하지만, JAVA는 그렇지 않다. 연산자 오버로딩은 단어 그대로 연산자를 재정의 하여 활용한다는 것인데, '객체'간 연산에 활용할 수 있다. (이를테면, *연산을 재정의하여 객체와 객체를 * 연산처리 할 수 있다.) JAVA는 만들어질 때부터 이러한 연산자 오버로딩을 지원하지 않는 방향으로 개발되었다고 한다.

 

둘째로, JAVA는 익명클래스(Anonymous Class)를 지원하지만, C++의 경우 그렇지 않다. 익명클래스는 JAVA에서 지원하는 기능인데, 말 그대로 이름이 없는 클래스이다. 인터페이스의 메소드 중 하나만 재정의하고 싶을 때 자주 사용되며, 클래스의 선언과 객체의 생성이 동시에 이루어지는 형태를 띄고 있다. JAVA는 익명클래스를 통해 '함수형 프로그래밍'의 형태를 어느 정도 흉내낼 수 있다.

셋째로, JAVA는 동적바인딩(Dynamic Binding)을 택하고 있지만, C++은 정적바인딩(Static Binding)을 택하고 있다. 하지만 C++이 정적바인딩만 지원하는 것은 아니고, virtual 키워드를 통해 동적바인딩을 지원한다.

※ 요약

  1. C++은 연산자오버로딩 지원, JAVA는 지원하지 않음.
  1. JAVA는 익명클래스 지원(함수형 프로그래밍을 어느정도 구현), C++은 지원하지 않음.
  1. JAVA는 동적바인딩, C++은 정적바인딩(virtual 키워드로 동적바인딩 가능)

 

기능c++Java
다중상속가능불가
Friend class가능불가
Interface불가가능
객체 생성stack, heapheap
Garbage Collection수동자동
연산자 오버로딩가능불가
익명클래스불가가능
바인딩 방식동적동적, 정적

출처:

http://preamtree.tistory.com/6

[Preamtree의 행복로그]

'Java' 카테고리의 다른 글

싱글톤 (Singleton)  (0) 2020.08.19
2. 객체지향 언어 특징  (0) 2018.07.26
2. 변수자료형연산자  (0) 2017.03.16
1. 기본 입출력  (0) 2017.03.16

03장-변수자료형연산자(강의).pdf


변수란?


값(value)이 저장된 메모리의 위치에 주어진 이름

변수에 값을 배정 할때  " = " 기호를 사용


int a = 10;   // a라는 변수에  10이라는 정수를 배정


식별자


int a = 10;에서 a는 식별자이다 . 변수를 정의할때 식별자를 보고 구분할수있음.


변수, 상수, 메소드,배열, 문자열, 사용자가 정의하는 클래스나 메소드 등을 구분할 수 있는 이름을 의미


식별자의 사용원칙 6가지

1. 식별자는 문자,숫자.특수문자로 구성가능 (한글 O,  공백X)

2. 첫문자는 문자나 특수문자로 시작

3. 길이 제한 없음.

4. 대소문자 구분 가능 (Sum != sum)

5. 예약어를 식별자로 사용 불가 (ex) for, if.switch)

6. true.false,null도 사용불가


클래스 이름 : 첫 글자는 대문자   ( ex) public static int Love() )

메소드,변수,배열,문자열 : 단어의 첫글자는 소문자 ( ex) string nameAndAge)

상수 : 모두 대문자  ( ex) int PI )

강제적 X


--------------------------------------------------------------------------------------------------------------------


JAVA의 자료형 


기본 자료형 - 정수형 (byte - 8bit, short - 16bit ,int - 32bit  ,long - 64bit  ,char - 16bit)    ,   실수형 (float , double)       ,       논리형 (boolean)

기본자료형은 값을 가진다!




참조 자료형  -  클래스 형(Class Type)   , 인터페이스 형 (Interface Type)  ,  배열형 (Array Type)  ,    열거 형 (Enumeration Type)

참조(주소)를 가진다!


【int형 변수에 값을 배정할때 정수 앞에 숫자 0을 하면 8진수 ,   0x를 붙여주면 16진수가 들어간다.

ex) int a = 0100;   a = 64(8진수)가 들어있음.

ex) int b = 0x100; b = 256(16진수)가 들어있음.



--------------------------------------------------------------------------------------------------------------------

실수형

float을 사용하려면 반드시 f를 붙여야한다.
float f = 3.14f  O
float f = 3.14   X
double d = 3.14 O
double d = 3.14d O

--------------------------------------------------------------------------------------------------------------------

확대 형 변환의 순서
byte -> short/char -> int -> long -> float -> double (자바는 묵시적으로 int는 정수, 실수는 double취급


--------------------------------------------------------------------------------------------------------------------

산술 연산자 (+ , - , * , / , % , ++ , --)


int a = 10;

System.out.println(a++);  // 10이 출력된후 +1 이됨.

int b = 10;

System.out.println(++a)        // 1이 먼저 증가한후 11이 출력됨


관계 연산자 ( > , >= , < , <= , == , != ,instanceof)

instanceof = 객체를 비교할때 사용함 , 다양하게 사용가능


논리 연산자 (&& ,  || [이항 논리]  , ![단항 논리]) )


--------------------------------------------------------------------------------------------------------------------

문자열

--------------------------------------------------------------------------------------------------------------------




연산자 우선순위 시험에 안나옴 !(중요하긴 한데 안나온다 하심 )





'Java' 카테고리의 다른 글

싱글톤 (Singleton)  (0) 2020.08.19
2. 객체지향 언어 특징  (0) 2018.07.26
1. Java란  (0) 2018.07.26
1. 기본 입출력  (0) 2017.03.16

import java.util.Scanner;


입력할때

Scanner Input = new Scanner(system.in);


int a = Input.nextInt();    // int형 입력받을때

string b = Input.next();   // string형 입력받을때

double c = Input.nextDouble();  // double형 입력받을때


------------------------------------------------------------------------------------------------------------------------------------------------------------------------


출력갈때

System.out.print(" ");

System.out.println(" ");            // ln은 줄바꿈 기능

'Java' 카테고리의 다른 글

싱글톤 (Singleton)  (0) 2020.08.19
2. 객체지향 언어 특징  (0) 2018.07.26
1. Java란  (0) 2018.07.26
2. 변수자료형연산자  (0) 2017.03.16

+ Recent posts