Ensuring Singletons

Singleton.java
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02 03package com.db4odoc.f1.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><b>Caution !!! This method contains a commit() call.</b> 19 */ 20 public static Object getSingleton(ObjectContainer objectContainer, Class clazz) { 21 22 Object obj = queryForSingletonClass(objectContainer, clazz); 23 if (obj != null) { 24 return obj; 25 } 26 27 String semaphore = "Singleton#getSingleton_" + clazz.getName(); 28 29 if (!objectContainer.ext().setSemaphore(semaphore, 10000)) { 30 throw new RuntimeException("Blocked semaphore " + semaphore); 31 } 32 33 obj = queryForSingletonClass(objectContainer, clazz); 34 35 if (obj == null) { 36 37 try { 38 obj = clazz.newInstance(); 39 } catch (InstantiationException e) { 40 e.printStackTrace(); 41 } catch (IllegalAccessException e) { 42 e.printStackTrace(); 43 } 44 45 objectContainer.set(obj); 46 47 /* !!! CAUTION !!! 48 * There is a commit call here. 49 * 50 * The commit call is necessary, so other transactions 51 * can see the new inserted object. 52 */ 53 objectContainer.commit(); 54 55 } 56 57 objectContainer.ext().releaseSemaphore(semaphore); 58 59 return obj; 60 } 61 62 private static Object queryForSingletonClass(ObjectContainer objectContainer, Class clazz) { 63 Query q = objectContainer.query(); 64 q.constrain(clazz); 65 ObjectSet objectSet = q.execute(); 66 if (objectSet.size() == 1) { 67 return objectSet.next(); 68 } 69 if (objectSet.size() > 1) { 70 throw new RuntimeException( 71 "Singleton problem. Multiple instances of: " + clazz.getName()); 72 } 73 return null; 74 } 75 76}