/* * Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.core; import com.hazelcast.config.Config; import com.hazelcast.logging.LoggingService; import com.hazelcast.partition.PartitionService; import java.util.Collection; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; /** * Factory for all of the Hazelcast data and execution components such as * maps, queues, multimaps, topics and executor service. * <p/> * If not started already, Hazelcast member (HazelcastInstance) will start * automatically if any of the functions is called on Hazelcast. */ @SuppressWarnings("SynchronizationOnStaticField") public final class Hazelcast { private static final AtomicReference<HazelcastInstance> defaultInstance = new AtomicReference<HazelcastInstance>(); private static final Object initLock = new Object(); private static Config defaultConfig = null; private Hazelcast() { } /** * Initializes the default Hazelcast instance with the specified configuration. * This method should be called before calling any other methods. * * @param config configuration for this Hazelcast instance. * @return the default instance * @throws IllegalStateException if this instance is already initialized */ public static HazelcastInstance init(Config config) { if (defaultInstance.get() != null) { throw new IllegalStateException("Default Hazelcast instance is already initialized."); } synchronized (initLock) { if (defaultInstance.get() != null) { throw new IllegalStateException("Default Hazelcast instance is already initialized."); } defaultConfig = config; HazelcastInstance defaultInstanceObject = com.hazelcast.impl.FactoryImpl.newHazelcastInstanceProxy(config); defaultInstance.set(defaultInstanceObject); return defaultInstanceObject; } } /** * Returns the default Hazelcast instance, starts it with the default * configuration, if not already started. * * @return the default Hazelcast instance */ public static HazelcastInstance getDefaultInstance() { HazelcastInstance defaultInstanceObject = defaultInstance.get(); if (defaultInstanceObject == null || !defaultInstanceObject.getLifecycleService().isRunning()) { synchronized (initLock) { defaultInstanceObject = defaultInstance.get(); if (defaultInstanceObject == null || !defaultInstanceObject.getLifecycleService().isRunning()) { defaultInstanceObject = com.hazelcast.impl.FactoryImpl.newHazelcastInstanceProxy(defaultConfig); defaultInstance.set(defaultInstanceObject); return defaultInstanceObject; } else { return defaultInstanceObject; } } } else { return defaultInstanceObject; } } /** * Returns the distributed queue instance with the specified name. * * @param name name of the distributed queue * @return distributed queue instance with the specified name */ public static <E> IQueue<E> getQueue(String name) { return getDefaultInstance().getQueue(name); } /** * Returns the distributed topic instance with the specified name. * * @param name name of the distributed topic * @return distributed topic instance with the specified name */ public static <E> ITopic<E> getTopic(String name) { return getDefaultInstance().getTopic(name); } /** * Returns the distributed set instance with the specified name. * * @param name name of the distributed set * @return distributed set instance with the specified name */ public static <E> ISet<E> getSet(String name) { return getDefaultInstance().getSet(name); } /** * Returns the distributed list instance with the specified name. * * @param name name of the distributed list * @return distributed list instance with the specified name */ public static <E> IList<E> getList(String name) { return getDefaultInstance().getList(name); } /** * Returns the distributed map instance with the specified name. * * @param name name of the distributed map * @return distributed map instance with the specified name */ public static <K, V> IMap<K, V> getMap(String name) { return getDefaultInstance().getMap(name); } /** * Returns the distributed multimap instance with the specified name. * * @param name name of the distributed multimap * @return distributed multimap instance with the specified name */ public static <K, V> MultiMap<K, V> getMultiMap(String name) { return getDefaultInstance().getMultiMap(name); } /** * Returns the distributed lock instance for the specified key object. * The specified object is considered to be the key for this lock. * So keys are considered equals cluster-wide as long as * they are serialized to the same byte array such as String, long, * Integer. * <p/> * Locks are fail-safe. If a member holds a lock and some of the * members go down, cluster will keep your locks safe and available. * Moreover, when a member leaves the cluster, all the locks acquired * by this dead member will be removed so that these locks can be * available for live members immediately. * <pre> * Lock lock = Hazelcast.getLock("PROCESS_LOCK"); * lock.lock(); * try { * // process * } finally { * lock.unlock(); * } * </pre> * * @param key key of the lock instance * @return distributed lock instance for the specified key. */ public static ILock getLock(Object key) { return getDefaultInstance().getLock(key); } /** * Returns the Cluster that this Hazelcast instance is part of. * Cluster interface allows you to add listener for membership * events and learn more about the cluster that this Hazelcast * instance is part of. * * @return cluster that this Hazelcast instance is part of */ public static Cluster getCluster() { return getDefaultInstance().getCluster(); } /** * Returns the default distributed executor service. Executor * service enables you to run your <tt>Runnable</tt>s and <tt>Callable</tt>s * on the Hazelcast cluster. * * Note that it don't support invokeAll/Any and don't have standard shutdown behavior * * @return distributed executor service of this Hazelcast instance */ public static ExecutorService getExecutorService() { return getDefaultInstance().getExecutorService(); } /** * Returns the distributed executor service for the given * name. * * @param name name of the executor service * @return executor service for the given name */ public static ExecutorService getExecutorService(String name) { return getDefaultInstance().getExecutorService(name); } /** * Returns the transaction instance associated with the current thread, * creates a new one if it wasn't already. * <p/> * Transaction doesn't start until you call <tt>transaction.begin()</tt> and * if a transaction is started then all transactional Hazelcast operations * are automatically transactional. * <pre> * Map map = Hazelcast.getMap("mymap"); * Transaction txn = Hazelcast.getTransaction(); * txn.begin(); * try { * map.put ("key", "value"); * txn.commit(); * }catch (Exception e) { * txn.rollback(); * } * </pre> * Isolation is always <tt>READ_COMMITTED</tt> . If you are in * a transaction, you can read the data in your transaction and the data that * is already committed and if not in a transaction, you can only read the * committed data. Implementation is different for queue and map/set. For * queue operations (offer,poll), offered and/or polled objects are copied to * the next member in order to safely commit/rollback. For map/set, Hazelcast * first acquires the locks for the write operations (put, remove) and holds * the differences (what is added/removed/updated) locally for each transaction. * When transaction is set to commit, Hazelcast will release the locks and * apply the differences. When rolling back, Hazelcast will simply releases * the locks and discard the differences. Transaction instance is attached * to the current thread and each Hazelcast operation checks if the current * thread holds a transaction, if so, operation will be transaction aware. * When transaction is committed, rolled back or timed out, it will be detached * from the thread holding it. * * @return transaction for the current thread */ public static Transaction getTransaction() { return getDefaultInstance().getTransaction(); } /** * Creates cluster-wide atomic long. Hazelcast AtomicNumber is a distributed * implementation of <tt>java.util.concurrent.atomic.AtomicLong</tt>. * * @param name of the AtomicNumber proxy * @return AtomicNumber proxy instance */ public static AtomicNumber getAtomicNumber(String name) { return getDefaultInstance().getAtomicNumber(name); } /** * Creates a cluster-wide CountDownLatch. Hazelcast ICountDownLatch is a distributed * implementation of <tt>java.util.concurrent.CountDownLatch</tt>. * * @param name of the distributed CountDownLatch * @return ICountDownLatch proxy instance */ public static ICountDownLatch getCountDownLatch(String name) { return getDefaultInstance().getCountDownLatch(name); } /** * Creates a cluster-wide semaphore. Hazelcast ISemaphore is a distributed * implementation of <tt>java.util.concurrent.Semaphore</tt>. * * @param name of the distributed Semaphore * @return ISemaphore proxy instance */ public static ISemaphore getSemaphore(String name) { return getDefaultInstance().getSemaphore(name); } /** * Creates cluster-wide unique IDs. Generated IDs are long type primitive values * between <tt>0</tt> and <tt>Long.MAX_VALUE</tt> . Id generation occurs almost at the speed of * <tt>AtomicLong.incrementAndGet()</tt> . Generated IDs are unique during the life * cycle of the cluster. If the entire cluster is restarted, IDs start from <tt>0</tt> again. * * @param name * @return IdGenerator proxy instance */ public static IdGenerator getIdGenerator(String name) { return getDefaultInstance().getIdGenerator(name); } /** * Detaches this member from the cluster. * It doesn't shutdown the entire cluster, it shuts down * this local member only. * * @see #getLifecycleService() * @deprecated as of version 1.9 */ public static void shutdown() { synchronized (initLock) { if (defaultInstance.get() != null) { getDefaultInstance().shutdown(); defaultInstance.set(null); } } } /** * Shuts down all running Hazelcast Instances on this JVM, including the * default one if it is running. It doesn't shutdown all members of the * cluster but just the ones running on this JVM. * * @see #newHazelcastInstance(Config) */ public static void shutdownAll() { com.hazelcast.impl.FactoryImpl.shutdownAll(); synchronized (initLock) { defaultInstance.set(null); } } /** * Detaches this member from the cluster first and then restarts it * as a new member. * * @see #getLifecycleService() * @deprecated as of version 1.9 */ public static void restart() { synchronized (initLock) { if (defaultInstance.get() != null) { getLifecycleService().restart(); } else { getDefaultInstance(); } } } /** * Returns all queue, map, set, list, topic, lock, multimap * instances created by Hazelcast. * * @return the collection of instances created by Hazelcast. */ public static Collection<Instance> getInstances() { return getDefaultInstance().getInstances(); } /** * Add a instance listener which will be notified when a * new instance such as map, queue, multimap, topic, lock is * added or removed. * * @param instanceListener instance listener */ public static void addInstanceListener(InstanceListener instanceListener) { getDefaultInstance().addInstanceListener(instanceListener); } /** * Removes the specified instance listener. Returns silently * if specified instance listener doesn't exist. * * @param instanceListener instance listener to remove */ public static void removeInstanceListener(InstanceListener instanceListener) { getDefaultInstance().removeInstanceListener(instanceListener); } /** * Creates a new HazelcastInstance (a new node in a cluster). * This method allows you to create and run multiple instances * of Hazelcast cluster members on the same JVM. * <p/> * To shutdown all running HazelcastInstances (all members on this JVM) * call {@link #shutdownAll()}. * * @param config Configuration for the new HazelcastInstance (member) * @return new HazelcastInstance * @see #shutdownAll() */ public static HazelcastInstance newHazelcastInstance(Config config) { return com.hazelcast.impl.FactoryImpl.newHazelcastInstanceProxy(config); } /** * Returns an existing HazelcastInstance with instanceName. * <p/> * To shutdown all running HazelcastInstances (all members on this JVM) * call {@link #shutdownAll()}. * * @param instanceName Name of the HazelcastInstance (member) * @return HazelcastInstance * @see #newHazelcastInstance(Config) * @see #shutdownAll() */ public static HazelcastInstance getHazelcastInstanceByName(String instanceName) { return com.hazelcast.impl.FactoryImpl.getHazelcastInstanceProxy(instanceName); } /** * Returns all active/running HazelcastInstances on this JVM. * <p/> * To shutdown all running HazelcastInstances (all members on this JVM) * call {@link #shutdownAll()}. * * @return all HazelcastInstances * @see #newHazelcastInstance(Config) * @see #getHazelcastInstanceByName(String) * @see #shutdownAll() */ public static Set<HazelcastInstance> getAllHazelcastInstances() { return com.hazelcast.impl.FactoryImpl.getAllHazelcastInstanceProxies(); } /** * Returns the configuration of this Hazelcast instance. * * @return configuration of this Hazelcast instance */ public static Config getConfig() { return getDefaultInstance().getConfig(); } /** * Returns the partition service of this Hazelcast instance. * PartitionService allows you to introspect current partitions in the * cluster, partition owner members and listen for partition migration events. * * @return partition service */ public static PartitionService getPartitionService() { return getDefaultInstance().getPartitionService(); } /** * Returns the logging service of this Hazelcast instance. * LoggingService allows you to listen for LogEvents * generated by Hazelcast runtime. You can log the events somewhere * or take action base on the message. * * @return logging service */ public static LoggingService getLoggingService() { return getDefaultInstance().getLoggingService(); } /** * Returns the lifecycle service for this instance. LifecycleService allows you * to shutdown, restart, pause and resume this HazelcastInstance and listen for * the lifecycle events. * * @return lifecycle service */ public static LifecycleService getLifecycleService() { return getDefaultInstance().getLifecycleService(); } }