Java Singleton Type Class
2023. 3. 30. 23:37ㆍJava
프로젝트 내 src 내 javabasic 패키지 내 SingleTonEx1.java
package javabasic;
public class SingleTonEx1 {// 인스턴스를 하나만 생성하고, 더이상 생성못함
private static SingleTonEx1 instance = new SingleTonEx1();
// 인스턴스를 하나만 생성하도록하는 싱글톤타입으로 클래스를 만드려면 생성자를
// private으로 외부에서 접근못하게 해야 한다 클래스생성자를 private으로설정
// static 키워드는 클래스를 로딩할 때 컴파일타임에 이미 만들어져버리기 때문에
// 실행중에 어떤 다른 처리가 필요하다면 불편하다
private SingleTonEx1() {
}
public static SingleTonEx1 getInstance() {
return instance;
}
}
프로젝트 내 src 내 javabasic 패키지 내 SingleTonEx2.java
package javabasic;
import java.util.Random;
public class SingleTonEx2 {
private static SingleTonEx2 instance = null;
private int randomNumber;
// 생성자를 private 이면 요 클래스 내에서만 생성할 수 있다는 것
private SingleTonEx2() {
}
// getInstance() 메소드를 호출하지 않는다면 아예 이클래스의 인스턴스는 생성안된다
// 한번도 생성되지않는 그런 패턴이 될수있다
public static SingleTonEx2 getInstance() {
if (instance == null) {
instance = new SingleTonEx2();
// SingleTonEx1은 클래스가 static이라 시작하자마자 바로 인스턴스가 생성되었지만 아예 객체가 미리 만들어져버리지만
// 요 SingleTonEx2는 getInstance()를 실행했을 때 동시에 바로 어떤 새로운 다른 처리를 할 수 있다.
Random rand = new Random();
// static 메소드에서는 non-static 변수를 못쓰므로
// instance의 randomNumber 자기자신의자식멤버로 접근한다
instance.randomNumber = rand.nextInt(5) + 1;
}
return instance;
}
public int getRandomNumber() {
return randomNumber;
}
}
프로젝트 내 src 내 javabasic 패키지 내 SingleTonEx3.java
package javabasic;
import java.util.Random;
public class SingleTonEx3 {
private static SingleTonEx3 instance = null;
private int randomNumber;
// 생성자를 private 이면 요 클래스 내에서만 생성할 수 있다는 것
private SingleTonEx3() {
}
// getInstance() 메소드를 호출하지 않는다면 아예 이클래스의 인스턴스는 생성안된다
// 한번도 생성되지않는 그런 패턴이 될수있다
// 객체를 두사람이 동시에 만들려고 이 클래스의 인스턴스를 동시에 만들면
// 객체가 2개 생길 문제가 있다. 그럴때 동기화 synchronized 를 쓴다
// 동시에 이 영역을 침범하지 못한다. 다른 프로그램은 먼저 또다른 프로그램이
// 이 영역을 쓰고 나서 요 자원을 쓴다. 두번째 예제를 해결...두번째예제는 첫예제를 해결
public static synchronized SingleTonEx3 getInstance() {
if (instance == null) {
instance = new SingleTonEx3();
// SingleTonEx1은 클래스가 static이라 시작하자마자 바로 인스턴스가 생성되었지만 아예 객체가 미리 만들어져버리지만
// 요 SingleTonEx2는 getInstance()를 실행했을 때 동시에 바로 어떤 새로운 다른 처리를 할 수 있다.
Random rand = new Random();
// static 메소드에서는 non-static 변수를 못쓰므로
// instance의 randomNumber 자기자신의자식멤버로 접근한다
instance.randomNumber = rand.nextInt(5) + 1;
}
return instance;
}
public int getRandomNumber() {
return randomNumber;
}
}
프로젝트 내 src 내 javabasic 패키지 내 SingleTonEx4.java
package javabasic;
import java.util.Random;
public class SingleTonEx4 {
private static SingleTonEx4 instance = null;
private int randomNumber;
// 생성자를 private 이면 요 클래스 내에서만 생성할 수 있다는 것
private SingleTonEx4() {
}
// getInstance() 메소드를 호출하지 않는다면 아예 이클래스의 인스턴스는 생성안된다
// 한번도 생성되지않는 그런 패턴이 될수있다
// 객체를 두사람이 동시에 만들려고 이 클래스의 인스턴스를 동시에 만들면
// 객체가 2개 생길 문제가 있다. 그럴때 동기화 synchronized 를 쓴다
// 동시에 이 영역을 침범하지 못한다. 다른 프로그램은 먼저 또다른 프로그램이
// 이 영역을 쓰고 나서 요 자원을 쓴다. 두번째 예제를 해결...두번째예제는 첫예제를 해결
// 이번에는 인스턴스화 하기 전의 작업.고작업만 동기화를 시켜줄것이다
// 함수전체에다 동기화걸지않고 생성직전에 영역만 잡아줄수있다.효율.
// 싱크로나이즈드 동기화 이용하면 여러가지 효율적면에서 좀 떨어지는 면이 있다
// 동시접근이 안되니깐 프로세스 처리가 길다고 가정하면 계속기다려야 하는 불편암이
// 있다.그래서 밑에 처럼 인스턴스화 하기 전의 생성 직전의 영역만 잡는다. 함수전체
// 보다는 좀더 효율적인 작업을 할 수 있다.
public static SingleTonEx4 getInstance() {
synchronized (SingleTonEx4.class) {
if (instance == null) {
instance = new SingleTonEx4();
// SingleTonEx1은 클래스가 static이라 시작하자마자 바로 인스턴스가 생성되었지만 아예 객체가 미리 만들어져버리지만
// 요 SingleTonEx2는 getInstance()를 실행했을 때 동시에 바로 어떤 새로운 다른 처리를 할 수 있다.
Random rand = new Random();
// static 메소드에서는 non-static 변수를 못쓰므로
// instance의 randomNumber 자기자신의자식멤버로 접근한다
instance.randomNumber = rand.nextInt(5) + 1;
}
}
return instance;
}
public int getRandomNumber() {
return randomNumber;
}
}
프로젝트 내 src 내 javabasic 패키지 내 SingleTonTest.java
package javabasic;
public class SingleTonTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("------------시작------------");
// 싱글톤 객체를 만들어야 하는데 우리는 싱클톤객체를 생성하지 못하고
// 반환만 받을수있다.
SingleTonEx1 singleton1 = SingleTonEx1.getInstance();
SingleTonEx1 singleton2 = SingleTonEx1.getInstance();
if (singleton1 == singleton2) {
System.out.println("서로 같은 객체입니다...");
} else {
System.out.println("서로 다른 객체입니다....");
System.out.println("-------------end-------------");
}
// SingleTonEx2 singleton3 = SingleTonEx2.getInstance();
// SingleTonEx2 singleton4 = SingleTonEx2.getInstance();
//
// if(singleton3 == singleton4) {
// System.out.println("서로 같은 객체입니다...");
// }else {
// System.out.println("서로 다른 객체입니다....");
// System.out.println("-------------end-------------");
// }
//
// System.out.printf("singleton3 : %d, singleton4 : %d\n", singleton3.getRandomNumber(), singleton4.getRandomNumber());
ThreadSt threadSt1 = new ThreadSt();
ThreadSt threadSt2 = new ThreadSt();
Thread thread1 = new Thread(threadSt1, "1");
Thread thread2 = new Thread(threadSt2, "2");
thread1.start();
thread2.start();
// System.out.println("-----SingleTonEx2 를 여러 사람이 동시에 만든다.-----");
//
// ThreadStEx2 threadStEx2_1 = new ThreadStEx2();
// ThreadStEx2 threadStEx2_2 = new ThreadStEx2();
// Thread thread3 = new Thread(threadStEx2_1, "3");
// Thread thread4 = new Thread(threadStEx2_2, "4");
//
// thread3.start();
// thread4.start();
}
}
class ThreadSt implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
for (int i = 0; i < 6; i = i + 1) {
// System.out.println("SingleTonEx2 : " + SingleTonEx2.getInstance().getRandomNumber());
// System.out.println("SingleTonEx3 : " + SingleTonEx3.getInstance().getRandomNumber());
// System.out.println("SingleTonEx4 : " + SingleTonEx4.getInstance().getRandomNumber());
// 위와 같이 SingleTonEx2, SingleTonEx3, SingleTonEx4 세 개를
// for 반복문에서 함께 돌리면 확률적으로 SingleTonEx2 객체에서 무작위수가
// 다른 값이 나올 경우가 낮아지기 때문에 SingleTonEx2 와 SingleTonEx3
// 두 개만 돌린다. 그러면 확률적으로 겹치지 않는 값이 나오고,
// SingleTonEx2 를 동시에 두 스레드가 run() 함수를 돌릴 때
// 싱글톤 패턴이 아닌 객체가 2개가 생기는 경우가 잘 나오게 된다.
// 위와 같이 생각하고 나서 아래와 같이 SingleTonEx2 와 SingleTonEx3
// 만 출력하도록 하였지만 SingleTonEx2, SingleTonEx3,
// SingleTonEx4 세 가지 다 출력하였을 때와 차이 없이 다른 값이 잘
// 나오지 않았다.그냥 계속 빠르게 연속적으로 Java Application 을
// 실행하지 않고 시간여유를 두면서 실행하거나 Remove All Terminated
// Launches 라는 Eclipse IDE 하단에 콘솔창에 콘솔탭 옆에 엑스2개표시를
// 누르고 다시 실행하다보면 어쩌다가 SingleTonEx2 객체 2개가 생기면서
// 랜덤값이 다르게
// 배정되어 나온다.
System.out.println("SingleTonEx2 : " + SingleTonEx2.getInstance().getRandomNumber());
System.out.println("SingleTonEx3 : " + SingleTonEx3.getInstance().getRandomNumber());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("실행 시간 : " + (end - start) / 1000.0);
// SingleTonEx3 와 SingleTonEx4 에서 동기화를 걸어주는 위치에 따라서
// 실행속도가 달라진다는 가정하에 시간을 재어보았지만 별 차이가 나지 않는다.
// 동기화를 걸어주는 함수 내에 프로세스 처리가 길어야 하는데 그렇지 않아서 그런 듯 하다..
}
}
class ThreadStEx2 implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 2; i++) {
System.out.println(SingleTonEx2.getInstance().getRandomNumber());
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
실행 결과
------------시작------------
서로 같은 객체입니다...
SingleTonEx2 : 0
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx3 : 3
SingleTonEx2 : 4
SingleTonEx3 : 3
실행 시간 : 1.275
실행 시간 : 1.275
프로젝트 내 src 내 javabasic 패키지 내 SingleTonTest2.java
package javabasic;
public class SingleTonTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("------------시작------------");
// 싱글톤 객체를 만들어야 하는데 우리는 싱클톤객체를 생성하지 못하고
// 반환만 받을수있다.
SingleTonEx1 singleton1 = SingleTonEx1.getInstance();
SingleTonEx1 singleton2 = SingleTonEx1.getInstance();
if (singleton1 == singleton2) {
System.out.println("서로 같은 객체입니다...");
} else {
System.out.println("서로 다른 객체입니다....");
System.out.println("-------------end-------------");
}
ThreadSt2 threadSt1 = new ThreadSt2();
ThreadSt2 threadSt2 = new ThreadSt2();
Thread thread1 = new Thread(threadSt1, "1");
Thread thread2 = new Thread(threadSt2, "2");
thread1.start();
thread2.start();
}
}
class ThreadSt2 implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
for (int i = 0; i < 6; i = i + 1) {
System.out.println("SingleTonEx2 : " + SingleTonEx2.getInstance().getRandomNumber());
System.out.println("SingleTonEx4 : " + SingleTonEx4.getInstance().getRandomNumber());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("실행 시간 : " + (end - start) / 1000.0);
}
}
실행 결과
------------시작------------
서로 같은 객체입니다...
SingleTonEx2 : 0
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx2 : 5
SingleTonEx2 : 5
SingleTonEx4 : 5
SingleTonEx4 : 5
실행 시간 : 1.272
실행 시간 : 1.273
'Java' 카테고리의 다른 글
Java getActionCommand() (0) | 2023.04.06 |
---|---|
Java ResultSetMetaData (0) | 2023.04.04 |
Java afterLast() (0) | 2023.03.28 |
Java JDBC™ 4.2 API (0) | 2023.02.28 |
Java - java.sql (0) | 2023.02.27 |