Ensuring Singletons

Singleton.java
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02 03package com.db4odoc.semaphores; 04 05import com.db4o.*; 06import com.db4o.query.*; 07 08/** 09 * This class demonstrates the use of a semaphore to ensure that only 10 * one instance of a certain class is stored to an ObjectContainer. 11 * 12 * Caution !!! The getSingleton method contains a commit() call. 13 */ 14public class Singleton { 15 16 /** 17 * returns a singleton object of one class for an ObjectContainer. 18 * <br> 19 * <b>Caution !!! This method contains a commit() call.</b> 20 */ 21 public static Object getSingleton( 22 ObjectContainer objectContainer, Class clazz) { 23 24 Object obj = queryForSingletonClass(objectContainer, clazz); 25 if (obj != null) { 26 return obj; 27 } 28 29 String semaphore = "Singleton#getSingleton_" 30 + clazz.getName(); 31 32 if (!objectContainer.ext().setSemaphore(semaphore, 10000)) { 33 throw new RuntimeException("Blocked semaphore " 34 + semaphore); 35 } 36 37 obj = queryForSingletonClass(objectContainer, clazz); 38 39 if (obj == null) { 40 41 try { 42 obj = clazz.newInstance(); 43 } catch (InstantiationException e) { 44 e.printStackTrace(); 45 } catch (IllegalAccessException e) { 46 e.printStackTrace(); 47 } 48 49 objectContainer.set(obj); 50 51 /* 52 * !!! CAUTION !!! There is a commit call here. 53 * 54 * The commit call is necessary, so other transactions can 55 * see the new inserted object. 56 */ 57 objectContainer.commit(); 58 59 } 60 61 objectContainer.ext().releaseSemaphore(semaphore); 62 63 return obj; 64 } 65 66 private static Object queryForSingletonClass( 67 ObjectContainer objectContainer, Class clazz) { 68 Query q = objectContainer.query(); 69 q.constrain(clazz); 70 ObjectSet objectSet = q.execute(); 71 if (objectSet.size() == 1) { 72 return objectSet.next(); 73 } 74 if (objectSet.size() > 1) { 75 throw new RuntimeException( 76 "Singleton problem. Multiple instances of: " 77 + clazz.getName()); 78 } 79 return null; 80 } 81 82}