The following code example demonstrates how to implement a clustered singleton.
import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache; /** * Singleton using cache to back it. (Commented out code is from a single-JVM * traditional singleton pattern. New code supports stateless session EJB * singleton pattern.) * * @author cp 2003.01.13 */ public class Singleton { // ----- constructors --------------------------------------------------- /** * Allow multiple instances to be instantiated; they will all share the * same state. */ public /*private*/ Singleton() { } // ----- properties ----------------------------------------------------- /** * Accessor for Name property. * * @return the current name value */ public String getName() { // return m_sName; return (String) m_cache.get("Name"); } /** * Mutator for Name property. * * @param sName the new name value */ public void setName(String sName) { // m_sName = sName; m_cache.put("Name", sName); } // more complex properties, such as hashtables, can be serialized into // the cache, but it is usually preferable to instantiate a separate // cache to replace complex objects such as a hashtable; instead of // exposing the hashtable as a property (i.e. "public Hashtable // getHashtable()"), it is better to expose the accessors and mutators // for the objects that the hashtable manages (i.e. "public Account[] // getAccounts()" and "public void addAccount(Account)" and "public void // removeAccount(Account)"). // ----- concurrency ---------------------------------------------------- /** * Lock the object in the cluster, and wait until the lock is available. * <p> * This is the cluster equivalent to the MONITORENTER Java opcode that * results from the Java synchronized keyword. * <p> * The non-clustered code would look like: * <pre><code> * synchronized (Singleton.INSTANCE) { * ... * } * </code></pre> * <p> * The clustered equivalent would look like: * <pre><code> * Singleton.INSTANCE.lock(); * try { * ... * } finally { * Singleton.INSTANCE.unlock(); * } * </code></pre> */ public void lock() { m_cache.lock("monitor", -1L); } /** * Unlock the object in the cluster. * <p> * This is the cluster equivalent to the MONITOREXIT Java opcode that * results from the Java synchronized keyword. */ public void unlock() { m_cache.unlock("monitor"); } // ----- data members --------------------------------------------------- /** * Singleton instance. (In a clustered environment, this will not be the * only instance.) */ public static final Singleton INSTANCE = new Singleton(); /** * Field storage for the Name property. */ // private String m_sName; /** * Cache storage for all properties. * Note, this uses the default replicated 'cache-mapping' that ships with the Coherence distribution. */ private final NamedCache m_cache = CacheFactory.getCache("repl-" + getClass().getName(), getClass().getClassLoader()); }