지속해서 업데이트 됩니다. (11/13)
ctrl + d를 눌러 북마크를 추가할 수 있습니다. 
모든 질문은 커뮤니티 Q&A 게시판에서 받습니다.


C/C++

  

C#



Python



Java



Android



HTML/CSS



JavaScript



PHP



DataStructure



Algorithm



Database



Network






안녕하세요 열코입니다.

이번시간에는 자바에서의 싱글톤 클래스에 대해 알아보도록 하겠습니다.


☞ 싱글톤 클래스란

객체지향 프로그래밍에서 싱글톤 클래스는 한번에 하나의 객체(Instance)만 가질 수 있는 클래스입니다.

싱글톤 클래스의 객체를 만들때 변수는 첫번째 객체를 가리킵니다.

따라서 어떤 객체를 통해 클래스 내부 변수를 수정하면 생성된 단일 객체의 변수에 영향을 미칩니다.



싱글톤 클래스를 만드는 방법

1. 생성자를 private으로 만듭니다.

2. 싱글톤 클래스를 반환 유형으로 한 정적 메소드를 작성합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MySingletonClass {
    private static MySingletonClass single_instance = null;
    
    private MySingletonClass() {
        
    }
    
    public static MySingletonClass getInstance() {
        if(single_instance == null) {
            single_instance = new MySingletonClass();
        }
        
        return single_instance;
    }
}
cs



일반 클래스 vs 싱글톤 클래스

일반 클래스의 경우 클래스를 정의할때 생성자를 사용하는 반면, 싱글톤 클래스의 경우 getInstance() 메소드를 사용합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Main {
    public static void main(String[] args) 
    {
        MySingletonClass singleton1 = MySingletonClass.getInstance();
        MySingletonClass singleton2 = MySingletonClass.getInstance();
        MySingletonClass singleton3 = MySingletonClass.getInstance();
        
        System.out.println(singleton1.s);
        System.out.println(singleton2.s);
        System.out.println(singleton3.s);
        
        singleton1.s = "Change String";
        
        System.out.println(singleton1.s);
        System.out.println(singleton2.s);
        System.out.println(singleton3.s);
    }
}
class MySingletonClass {
    private static MySingletonClass single_instance = null;
    
    public String s;
    
    private MySingletonClass() {
        s = "MySingletonClass";
    }
    
    public static MySingletonClass getInstance() {
        if(single_instance == null) {
            single_instance = new MySingletonClass();
        }
        
        return single_instance;
    }
}
cs


4번째 줄에 MySingletonClass라는 제가 정의한 싱글톤 클래스의 객체(인스턴스)를 3개 만드는 것을 볼 수 있습니다.

일반 클래스의 경우 class a = new class(); 이런식으로 객체를 생성하는것과 달리

싱글톤 클래스의 경우 getInstance() 메소드를 호출하여 객체를 생성하는 모습입니다.


8,9,10번 줄의 결과는 어떻게될까요?

아시다시피 s는 "MySingletonClass"라는 문자열입니다. 이 문자열이 3번 출력됩니다.


12번째 줄에서 첫번째 싱글톤 객체의 s를 "Change String"으로 변경했습니다.


그 다음에 출력을 해보면 어떤 결과가 나올까요?

첫번째 싱글톤 객체의 s만 바꿨기 때문에

ChangeString

MySingletonClass
MySingletonClass

가 나올것 같지만 아닙니다!!


싱글톤 클래스는 위에서 말씀드렸다시피 여러 객체를 생성해도 하나의 객체만 가리키고 있기 때문에

MySingletonClass

MySingletonClass
MySingletonClass

의 출력 결과를 가집니다.


singleton1, singleton2, singleton3 모두 하나의 클래스 객체를 가리키고 있는것이죠.



질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.





안녕하세요 열코입니다.

이번시간에는 자바의 가비지 컬렉션에 대해 알아보겠습니다.


우리가 C/C++ 프로그래밍을 할 때 메모리 누수(Memory Leak)를 막기 위해 객체를 생성한 후 

사용하지 않는 객체를 파괴(메모리 해제)를 프로그래머가 직접 해주어야 했습니다.


하지만 Java에서는 JVM(Java Virtual Machine)이 구성된 JRE(Java Runtime Environment)가 

제공되며 JVM 구성 요소 중 하나인 가비지 컬렉션(Garbage Collection)이 자동으로 

사용하지 않는 객체를 파괴합니다.


JVM의 가비지 컬렉션은 다음과 같은 단계로 메모리 해제 작업을 수행합니다.

1. 마킹 작업 : 사용중인 메모리와 사용 하지않는 메모리를 식별합니다.

2. 일반 삭제 : 참조되지 않는 객체를 제거하고 빈 공간에 대한 포인터를 남겨둡니다.

+ 압축 삭제 : 삭제 된 객체 외 나머지 객체를 메모리 공간을 효율적으로 사용하며 삭제


또한 JVM의 가비지 컬렉션은 객체들을 세대로 나누어 처리합니다.

- 젊은 세대 : 새로운 모든 객체를 할당하는 곳입니다. 젊은 세대가 가득차면 가비지 컬렉션을 수행하며 

매우 빠른 속도로 진행됩니다. 사소한(가벼운) 가비지 컬렉션이 수행됩니다.

- 이전 세대 : 오랫동안 생존한 객체를 저장합니다. 젊은 세대에서 생성된 객체에 임계 값을 주어지고 어느정도

연령에 도달하면 이전 세대로 이동합니다. 이전 세대의 객체를 수집하는 것을 주요 가비지 컬렉션이라고 합니다.


세대 별 가비지 컬렉션은 다음과 같은 과정으로 수행됩니다.

1. 새로운 객체는 에덴(Eden) 공간에 할당되며, 그 외 두 개의 생존 공간이 모두 비어있는 상태입니다.

2. 에덴 공간이 가득차게 되면 사소한(가벼운) 가비지 컬렉션이 시작됩니다.

3. 참조된 객체는 첫번째 생존 공간으로 이동되며 참조되지 않는 객체는 모두 삭제됩니다.

4. 가비지 컬렉션이 수행되는 동안 첫번째 생존 공간의 객체들은 특정 임계값이 넘어가면 두번째 생존 공간으로 이동합니다.

5. 두 번째 생존 공간의 객체들도 특정 임계값이 넘어가면 이전 세대로 넘어가게 됩니다.

6. 이전 세대의 객체가 일정 크기 이상 수집되면 주요 가비지 컬렉션이 수행됩니다.


또한 다음과 같이 JVM에게 가비지 컬렉션을 실행하도록 요청할 수 있습니다.

System.gc() 메소드 또는 Runtime.getRuntime().gc() 메소드 사용 (수행되는 가비지 컬렉션은 동일합니다.)



아래는 객체를 가비지 컬렉션의 대상으로 만드는 방법입니다.

1. 메소드 내부에서 생성된 객체

class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


static void show() {

GCTest gct1 = new GCTest("gct1");

show2();

}

static void show2() {

GCTest gct2 = new GCTest("gct2");

}


public static void main(String[] args) {

show();

System.gc(); //  gct1과 gct2는 가비지 컬렉션의 대상이 됨.

}

}

위 코드와 같이 메소드가 호출된 후 내부에 일부 객체가 만들어지고 메소드가 종료됬을 때, 메소드 내부의 객체들은

익명이 되어 가비지 컬렉션의 대상이 됩니다.


2. 참조 변수 재 지정

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

GCTest gct1 = new GCTest("gct1");

GCTest gct2 = new GCTest("gct2");


gct1 = gct2;


System.gc();

}

}

위 코드는 한 객체의 참조가 다른 객체를 참조할 때 이전 객체는 더 이상 참조를 갖지 못해 가비지 컬렉션의 대상이 됩니다.


3. 참조 변수 무효화

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

GCTest gct1 = new GCTest("gct1");


gct1 = null;


System.gc();

}

}

위 코드는 객체의 참조 변수가 null로 변경되었기 때문에 가비지 컬렉션의 대상이 됩니다.



4. 익명 객체

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

new GCTest("gct1");


System.gc();

}

}

익명 객체의 참조는 어느곳에도 저장되지 않기 때문에 가비지 컬렉션의 대상이 됩니다.



이상 '자바 가비지 컬렉션'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.





안녕하세요 열코입니다.


이번에는 자바에서 크기가 동적인 배열을 사용할 때 주로 사용하는 

두가지 클래스 벡터(Vector)와 어레이리스트(ArrayList)에 대해 

비교분석 해보겠습니다.


먼저 벡터에 대한 설명입니다.


☞ Vector란?

- 벡터 클래스는 예전의 자바에서 제공했던 레거시 클래스입니다.

- 레거시 클래스란 Collections 프레임워크가 포함되어 있지 않던 초기 자바 버전에서 정의한 인터페이스입니다.

- 현재는 재구성 및 설계되어서 현재의 Collections 프레임워크와 완벽하게 호환됩니다.


 Vector의 특징

- 필요에 따라 크기를 동적으로 조절할 수 있는 동적배열을 구현합니다.

- 배열과 마찬가지로 정수 인덱스를 이용하여 배열에 액세스 할 수 있습니다.

- 동기화(Thread Safe) 되어있으며 한번에 하나의 스레드만 벡터의 메소드를 호출 할 수 있습니다.


※ 벡터에 대한 사용법은 추후에 포스팅하겠습니다.



다음 어레이리스트에 대한 설명입니다.


☞ ArrayList란?

- Collections 프레임워크의 일부이며 java.uitl 패키지 내에 존재합니다.

- 벡터와 마찬가지로 동적 배열을 사용하기 위해 사용됩니다.


☞ ArrayList의 특징

- 자바 표준 배열보다 약간 느릴수 있지만 배열에서 많은 조작이 필요로할때 유용하게 사용됩니다.

- 기본 데이터 타입(int, char 등)에 대해 만들수 없기때문에 Integer, Object 등의 객체에 대해 참조해서 사용합니다.


※ 어레이리스트에 대한 사용법은 추후에 포스팅하겠습니다.



이렇게 비슷한 두 클래스 벡터와 어레이리스트의 차이점은 무엇이며 어떤 상황에서 어떤 클래스를 사용 야 하는

지에 대해 알아보겠습니다.

실제로 두 클래스는 많은 차이점이 있지만 이 포스트에서는 주요 차이점에 대해서만 언급하겠습니다.


ArrayList와 Vector의 주요 차이점


1. 동기화(Synchronize)

Vector가 동기화 된다면 ArrayList는 동기화가 되지않은 상태입니다.

쉽게말해 Vector는 한번에 하나의 스레드만 엑세스(접근) 가능하며, ArrayList는 동시에 여러 스레드가 

작업할 수 있습니다.

ArrayList에서 여러 스레드가 동시에 엑세스하는 경우 개발자가 명시적으로 동기화하는 코드를 추가해야합니다.



2. 스레드 안전(Thread Safe)

스레드 안전이란 멀티 스레드 프로그래밍에서 여러 스레드가 동시에 접근이 이루어져도 프로그램 실행에 

문제가 없음을 뜻합니다.

앞서 말했듯이 Vector는 동기화 되어있기 때문에 한번에 하나의 스레드만 접근할 수 있기때문에 스레드 

안전합니다.

ArrayList는 동기화되지 않았기 때문에 명시적으로 동기화 할 필요가 있습니다.

 

3. 성능

ArrayList는 동기화 되지않았기 때문에 동기화 된 벡터보다 더 빠릅니다.


4. 크기 증가

Vector와 ArrayList 모두 동적 배열 클래스로 최대 인덱스를 초과할 때 추가되는 인덱스 수가 다릅니다.

Vector는 현재 배열의 크기의 100%가 증가하며, ArrayList의 경우 현재 배열의 크기의 50%가 증가합니다.



★ 결론

멀티스레드 환경이 아닌 경우 ArrayList를 사용하는것이 바람직합니다.

Vector를 사용하기 위한 명시적 요구 사항이 없는경우 ArrayList를 사용하도록 합시다.



이상 '자바 벡터와 어레이리스트의 비교'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.





이번에는 Java Eclipse에서 JDBC를 통해 Mysql DB를 연동하는 방법에 대해 알아보겠습니다.

- JDBC란? Java DataBase Connectivity로 자바에서 데이터베이스에 접속 할 수 있도록 자바에서 제공하는 API입니다. 


* 환경
JDK : jdk1.8.0_171
자바 개발 툴 : eclipse-jee-oxygen-3a-win32
데이터베이스 : MySQL 5.1.41-community

* 소스코드
import java.sql.*; 

public class dbtest { 
          public static void main(String arg[]) throws Exception { 
                    Connection conn; 
                    Statement stmt; 
                    ResultSet rs; 

                    Class.forName("com.mysql.jdbc.Driver");  // JDBC driver를 메모리에 로드
                    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB명", 
                              "ID", "PASSWORD"); 
                    stmt = (Statement) conn.createStatement(); 
                    rs=stmt.executeQuery("SELECT * FROM TABLE명");  // 원하는 쿼리문 실행

                    while(rs.next()) { 
                              System.out.print(rs.getString("id") + " ");  
                              System.out.println(rs.getString("password")); 
                    

                    rs.close(); 
                    stmt.close(); 
                    conn.close();
          
}

코드는 매우 간단합니다.
먼저 JDBC Driver를 사용하기 위해 Class.forName을 사용하여 메모리에 등록하고
DriverManager를 통해 DB에 접속합니다.
그리고 쿼리를 준비하고 원하는 쿼리문을 실행하고 받은 데이터를 처리합니다.
마지막으로 정상적인 처리를 위해 사용한 객체들을 역순으로 닫아주면 됩니다.

위 SELECT 문 사용 예제를 통해 INSERT, DELETE, UPDATE 문을 활용하여 프로그램을 제작해 보면
어떨까요?

에러나 질문사항은 댓글로 달아주세요.



to Top