Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- cookie
- InvocationHandler
- getRequestURI
- Transfer-Encoding
- Java
- object
- urlclassloader
- unmodifiableList
- Session
- Content-Length
- Reference
- Proxy
- chunked
- http
- toString
- reflection
- singleton
- http/1.1
- clone
- Keep-Alive
Archives
- Today
- Total
pungjoo
작성중 - Singleton에 대한 이해. 본문
0. 들어가면서
( 이미지는 Romm이네 이런.... 프로젝트 이름이 뭐 중요한가 그냥 ...)
3. 추상클래스 및 구현체 작성
00-commonRoom 프로젝트에서....
4. 테스트
결과
위 소스에서 붉은 색 부분을 다른 형태로
결과
5. 구현 클래스 및 테스트 클래스를 SingletonRoom 프로젝트로 이동
(1)과 같이 00-commonRoom 프로젝트에서 SingletonRoom으로 클래스 파일을 옮기면 ( 이미지는 Romm이네 이런.... )
(2)와 같이 오류가 발생하는데 이는 SingletonRoom 프로젝트에는 info.yeonwoo.edu.Singleton.class가 없기때문입니다.
SingletonRoom의 properties-> Java Build Path -> Projects -> Add -> 00-commonRoom 추가.
SingletonRoom 프로젝트로 옮긴 후 SingletonTest1 / SingletonTest2 를 각각 실행해 보세요. 결과는 동일함.
6. 이제 하고 싶은 말을 해 보자...
다시 00-commonRoom에 다음과 같은 Test 클래스를 만들어 보면... 위 Test2를 조금 변형 시켜서...
결과
그럼 이런건 어떨까?
SingletonRoom 프로젝트에서
결과
어쩌구 저쩌구~~~~~
이쯤에서 디렉토리 구조를 살펴 보면..
7. 결론...
어쩌구 저쩌구가 이래서 저래서 그렇다..
해당 소스를 이클립스에서 import하세요. ( general -> Existing Projeccts into Workspace -> Select archive file )
@
일반적으로 singleton에 대해 설명하는 글을 보면 JVM상에 유일하게 인스턴화된 객체라고 표현합니다.
그러나 이는 엄밀히 말하면 JVM상에 classloader에 따른 유일하게 인스턴화된 객체가 맞는 표현입니다.
주의 : 싱글 인스턴를 만드는 방법을 설명하는 글이 아닙니다.
1. 경험
tomcat기준으로 1개의 process(jvm)에는 기본적으로 1개의 context를 정의해 사용하나 여러개의 context를 등록해 uri path로 구분해 서비스할 수 있습니다. 이런 경우에 과연 각각 context마다 WEB-INF/classes에 놓여 있는 singleton class가 jvm하에서 유일할까요? 어쩌구 저쩌구
2. 프로젝트 만들기 ( 편의상 이클립스 사용 )
다음과 같이 2개의 Java Project를 생성합니다.
( 이미지는 Romm이네 이런.... 프로젝트 이름이 뭐 중요한가 그냥 ...)
3. 추상클래스 및 구현체 작성
00-commonRoom 프로젝트에서....
package info.yeonwoo.edu;
public abstract class Singleton {
abstract public void printSum();
}
public abstract class Singleton {
abstract public void printSum();
}
package info.yeonwoo.edu;
import info.yeonwoo.edu.Singleton;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
final public class SingletonImpl extends Singleton {
final static private SingletonImpl INSTANCE = new SingletonImpl();
final AtomicInteger counter = new AtomicInteger();
private SingletonImpl() {
}
@Override
public void printSum() {
Thread t = new Thread() {
public void run() {
AtomicLong sum = new AtomicLong();
for (int loop = 0; loop < 10; loop++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
sum.addAndGet(counter.incrementAndGet());
}
System.out.println(Thread.currentThread() + " : Sum = " + sum.get());
}
};
t.start();
}
public static Singleton getInstance() {
return INSTANCE;
}
}
import info.yeonwoo.edu.Singleton;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
final public class SingletonImpl extends Singleton {
final static private SingletonImpl INSTANCE = new SingletonImpl();
final AtomicInteger counter = new AtomicInteger();
private SingletonImpl() {
}
@Override
public void printSum() {
Thread t = new Thread() {
public void run() {
AtomicLong sum = new AtomicLong();
for (int loop = 0; loop < 10; loop++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
sum.addAndGet(counter.incrementAndGet());
}
System.out.println(Thread.currentThread() + " : Sum = " + sum.get());
}
};
t.start();
}
public static Singleton getInstance() {
return INSTANCE;
}
}
4. 테스트
package info.yeonwoo.edu;
import info.yeonwoo.edu.Singleton;
public class SingletonTest1 {
public static void main(String[] args) {
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
Singleton obj = SingletonImpl.getInstance();
obj.printSum();
}
}
}
import info.yeonwoo.edu.Singleton;
public class SingletonTest1 {
public static void main(String[] args) {
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
Singleton obj = SingletonImpl.getInstance();
obj.printSum();
}
}
}
결과
Thread[Thread-0,5,main] : Sum = 235
Thread[Thread-1,5,main] : Sum = 245
Thread[Thread-2,5,main] : Sum = 255
Thread[Thread-4,5,main] : Sum = 265
Thread[Thread-3,5,main] : Sum = 275
Thread[Thread-1,5,main] : Sum = 245
Thread[Thread-2,5,main] : Sum = 255
Thread[Thread-4,5,main] : Sum = 265
Thread[Thread-3,5,main] : Sum = 275
위 소스에서 붉은 색 부분을 다른 형태로
package info.yeonwoo.edu;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
public class SingletonTest2 {
public static void main(String[] args) throws Exception {
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
URLClassLoader uc = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class clazz = uc.loadClass("info.yeonwoo.edu.SingletonImpl");
Method method = clazz.getMethod("getInstance", new Class[] {});
Singleton obj = (Singleton) method.invoke(new Object[] {}, new Object[] {});
obj.printSum();
}
}
}
import java.lang.reflect.Method;
import java.net.URLClassLoader;
public class SingletonTest2 {
public static void main(String[] args) throws Exception {
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
URLClassLoader uc = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class clazz = uc.loadClass("info.yeonwoo.edu.SingletonImpl");
Method method = clazz.getMethod("getInstance", new Class[] {});
Singleton obj = (Singleton) method.invoke(new Object[] {}, new Object[] {});
obj.printSum();
}
}
}
결과
Thread[Thread-1,5,main] : Sum = 248
Thread[Thread-4,5,main] : Sum = 272
Thread[Thread-2,5,main] : Sum = 249
Thread[Thread-0,5,main] : Sum = 240
Thread[Thread-3,5,main] : Sum = 266
Thread[Thread-4,5,main] : Sum = 272
Thread[Thread-2,5,main] : Sum = 249
Thread[Thread-0,5,main] : Sum = 240
Thread[Thread-3,5,main] : Sum = 266
5. 구현 클래스 및 테스트 클래스를 SingletonRoom 프로젝트로 이동
(1)과 같이 00-commonRoom 프로젝트에서 SingletonRoom으로 클래스 파일을 옮기면 ( 이미지는 Romm이네 이런.... )
(2)와 같이 오류가 발생하는데 이는 SingletonRoom 프로젝트에는 info.yeonwoo.edu.Singleton.class가 없기때문입니다.
SingletonRoom의 properties-> Java Build Path -> Projects -> Add -> 00-commonRoom 추가.
SingletonRoom 프로젝트로 옮긴 후 SingletonTest1 / SingletonTest2 를 각각 실행해 보세요. 결과는 동일함.
6. 이제 하고 싶은 말을 해 보자...
다시 00-commonRoom에 다음과 같은 Test 클래스를 만들어 보면... 위 Test2를 조금 변형 시켜서...
package info.yeonwoo.edu;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class SingletonTest3 {
public static void main(String[] args) throws Exception {
File file = new File("../SingletonRoom/bin/");
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
URLClassLoader uc = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class clazz = uc.loadClass("info.yeonwoo.edu.SingletonImpl");
Method method = clazz.getMethod("getInstance", new Class[] {});
Singleton obj = (Singleton) method.invoke(new Object[] {}, new Object[] {});
obj.printSum();
}
}
}
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class SingletonTest3 {
public static void main(String[] args) throws Exception {
File file = new File("../SingletonRoom/bin/");
for (int mainLoop = 0; mainLoop < 5; mainLoop++) {
URLClassLoader uc = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class clazz = uc.loadClass("info.yeonwoo.edu.SingletonImpl");
Method method = clazz.getMethod("getInstance", new Class[] {});
Singleton obj = (Singleton) method.invoke(new Object[] {}, new Object[] {});
obj.printSum();
}
}
}
결과
Thread[Thread-0,5,main] : Sum = 55
Thread[Thread-2,5,main] : Sum = 55
Thread[Thread-1,5,main] : Sum = 55
Thread[Thread-3,5,main] : Sum = 55
Thread[Thread-4,5,main] : Sum = 55
Thread[Thread-2,5,main] : Sum = 55
Thread[Thread-1,5,main] : Sum = 55
Thread[Thread-3,5,main] : Sum = 55
Thread[Thread-4,5,main] : Sum = 55
그럼 이런건 어떨까?
SingletonRoom 프로젝트에서
package info.yeonwoo.edu;
public class SingletonTest4 {
public static void main(String[] args) throws Exception {
SingletonTest3.main(null);
}
}
public class SingletonTest4 {
public static void main(String[] args) throws Exception {
SingletonTest3.main(null);
}
}
결과
Thread[Thread-1,5,main] : Sum = 235
Thread[Thread-2,5,main] : Sum = 245
Thread[Thread-3,5,main] : Sum = 258
Thread[Thread-4,5,main] : Sum = 262
Thread[Thread-0,5,main] : Sum = 275
Thread[Thread-2,5,main] : Sum = 245
Thread[Thread-3,5,main] : Sum = 258
Thread[Thread-4,5,main] : Sum = 262
Thread[Thread-0,5,main] : Sum = 275
어쩌구 저쩌구~~~~~
이쯤에서 디렉토리 구조를 살펴 보면..
7. 결론...
어쩌구 저쩌구가 이래서 저래서 그렇다..
8. 소스
해당 소스를 이클립스에서 import하세요. ( general -> Existing Projeccts into Workspace -> Select archive file )
@
Comments