POOPOO: 배변 일기 앱
SMALL
생성패턴 목록
- 팩토리 메소드 패턴 (Factory Method Pattern)
- 추상 팩토리 패턴 (Abstract Factory Pattern)
- 싱글톤 패턴 (Singleton Pattern)
- 프로토타입 패턴 (Prototype Pattern)
- 빌더 패턴 (Builder Pattern)
- 오브젝트 풀 패턴 (Object Pool Pattern)
스레드 풀과 같이 한정된 리소스에서 자원을 재사용하는 방식을 적용하기를 원할 때 사용하면 성능개선에 좋을 것 같다.
장점
- 응용프로그램의 성능을 크게 향상시킵니다.
- 클래스 인스턴스 초기화 속도가 높은 상황에서 가장 효과적입니다.
- 커넥션을 관리하고 이를 재사용하고 공유할 수 있는 방법을 제공합니다.
- 만들 수 있는 최대 객체 수에 대한 제한을 제공할 수 있습니다.
사용시기
- 어플리케이션에서 사용하기에 비용이 높은 객체가 필요한 경우 (데이터베이스 커넥션)
- 서로 다른 시간에 동일한 리소스를 필요로 하는 여러 클라이언트가 있는 경우
UML
ObjectPool Class : ObjectPool
public abstract class ObjectPool<T>{
private ConcurrentLinkedQueue<T> pool;
private ScheduledExecutorService executorService;
public ObjectPool(final int minObjects){
initialize(minObjects);
}
public ObjectPool(final int minObjects, final int maxObjects, final long validationInterval){
initialize(minObjects);
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable(){
@Override
public void run(){
int size = pool.size();
if(size < minObjects){
int sizeToBeAdded = minObjects + size;
for(int i=0; i<sizeToBeAdded; i++){
pool.add(createObject());
}
}
else if(size > maxObjects){
int sizeToBeRemoved = size - maxObjects;
for(int i=0; i<sizeToBeRemoved; i++){
pool.poll();
}
}
}
}, validationInterval, validationInterval, TimeUnit.SECONDS);
}
public T borrowObject(){
T object;
if((object = pool.poll()) == null){
object = createObject();
}
return object;
}
public void returnObject(T object){
if(object == null){
return;
}
this.pool.offer(object);
}
public void shutdown(){
if(executorService != null){
executorService.shutdown();
}
}
protected abstract T createObject();
private void initialize(final int minObjects){
pool = new ConcurrentLinkedQueue<T>();
for(int i=0; i<minObjects; i++){
pool.add(creatObject());
}
}
}
Process Class : ExportingProcess, ExportingTask
public class ExportingProcess{
private long processNo;
public ExportingProcess(long processNo){
this.processNo = processNo;
System.out.println("Object with process no. " + processNo + " was created");
}
public long getProcessNo(){
return processNo;
}
}
public class ExportingTask implements Runnable{
private ObjectPool<ExportingProcess> pool;
private int threadNo;
public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo){
this.pool = pool;
this.threadNo = threadNo;
}
public void run(){
ExportingProcess exportingProcess = pool.borrowObject();
System.out.println("Thread " + threadNo + ": Object with process no. "
+ exportingProcess.getProcessNo() + " was borrowed");
pool.returnObject(exportingProcess);
System.out.println("Thread " + threadNo +": Object with process no. "
+ exportingProcess.getProcessNo() + " was returned");
}
}
Operation Class : ObjectPoolDemo
public class ObjectPoolDemo{
private ObjectPool<ExportingProcess> pool;
private AtomicLong processNo=new AtomicLong(0);
public void setUp(){
pool = new ObjectPool<ExportingProcess>(4, 10, 5){
@Override
protected ExportingProcess createObject(){
return new ExportingProcess(processNo.incrementAndGet());
}
}
}
public void tearDown(){
pool.shutdown();
}
public void testObjectPool(){
ExecutorService executor = Executors.newFixedThreadPool(8);
executor.execute(new ExportingTask(pool, 1));
executor.execute(new ExportingTask(pool, 2));
executor.execute(new ExportingTask(pool, 3));
executor.execute(new ExportingTask(pool, 4));
executor.execute(new ExportingTask(pool, 5));
executor.execute(new ExportingTask(pool, 6));
executor.execute(new ExportingTask(pool, 7));
executor.execute(new ExportingTask(pool, 8));
executor.shutdown();
try{
executor.awaitTermination(30, TimeUnit.SECONDS);
}catch(InterruptedException e){
e.printStackTrace();
}
}
public static void main(String[] args){
ObjectPoolDemo op = new ObjectPoolDemo();
op.setUp();
op.tearDown();
op.testObjectPool();
}
}
출처 : https://www.javatpoint.com/
LIST