参考文章:https://blog.csdn.net/u013256816/article/details/50427061
描述
Singleton(单例)是设计模式的一种,为了保证一个类仅有一个实例,并提供一个访问它的全局访问点。
捕获.PNG
特点
- 单例类确保自己只有一个实例(构造函数私有:不被外部实例化,也不被继承)。
- 单例类必须自己创建自己的实例。
- 单例类必须为其他对象提供唯一的实例。
单例—枚举
/**
* Enum based singleton implementation. Effective Java 2nd Edition (Joshua Bloch) p. 18
*
* This implementation is thread safe, however adding any other method and its thread safety
* is developers responsibility.
*/
public enum EnumIvoryTower {
INSTANCE;
@Override
public String toString() {
return getDeclaringClass().getCanonicalName() + "@" + hashCode();
}
}
单例—单例类
/**
* Singleton class. Eagerly initialized static instance guarantees thread safety.
*/
public final class IvoryTower {
/**
* Private constructor so nobody can instantiate the class.
*/
private IvoryTower() {}
/**
* Static to class instance of the class.
*/
private static final IvoryTower INSTANCE = new IvoryTower();
/**
* To be called by user to obtain instance of the class.
*
* @return instance of the singleton.
*/
public static IvoryTower getInstance() {
return INSTANCE;
}
}
单例—懒加载
/**
* The Initialize-on-demand-holder idiom is a secure way of creating a lazy initialized singleton
* object in Java.
* <p>
* The technique is as lazy as possible and works in all known versions of Java. It takes advantage
* of language guarantees about class initialization, and will therefore work correctly in all
* Java-compliant compilers and virtual machines.
* <p>
* The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than
* the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special
* language constructs (i.e. volatile or synchronized).
*
*/
public final class InitializingOnDemandHolderIdiom {
/**
* Private constructor.
*/
private InitializingOnDemandHolderIdiom() {}
/**
* @return Singleton instance
*/
public static InitializingOnDemandHolderIdiom getInstance() {
return HelperHolder.INSTANCE;
}
/**
* Provides the lazy-loaded Singleton instance.
*/
private static class HelperHolder {
private static final InitializingOnDemandHolderIdiom INSTANCE =
new InitializingOnDemandHolderIdiom();
}
}
单例—Thread-safe Singleton class
/**
* Thread-safe Singleton class. The instance is lazily initialized and thus needs synchronization
* mechanism.
*
* Note: if created by reflection then a singleton will not be created but multiple options in the
* same classloader
*/
public final class ThreadSafeLazyLoadedIvoryTower {
private static ThreadSafeLazyLoadedIvoryTower instance;
private ThreadSafeLazyLoadedIvoryTower() {
// protect against instantiation via reflection
if (instance == null) {
instance = this;
} else {
throw new IllegalStateException("Already initialized.");
}
}
/**
* The instance gets created only when it is called for first time. Lazy-loading
*/
public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() {
if (instance == null) {
instance = new ThreadSafeLazyLoadedIvoryTower();
}
return instance;
}
}
单例—Double check locking
/**
* Double check locking
* <p>
* http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
* <p>
* Broken under Java 1.4.
*
* @author mortezaadi@gmail.com
*/
public final class ThreadSafeDoubleCheckLocking {
private static volatile ThreadSafeDoubleCheckLocking instance;
/**
* private constructor to prevent client from instantiating.
*/
private ThreadSafeDoubleCheckLocking() {
// to prevent instantiating by Reflection call
if (instance != null) {
throw new IllegalStateException("Already initialized.");
}
}
/**
* Public accessor.
*
* @return an instance of the class.
*/
public static ThreadSafeDoubleCheckLocking getInstance() {
// local variable increases performance by 25 percent
// Joshua Bloch "Effective Java, Second Edition", p. 283-284
ThreadSafeDoubleCheckLocking result = instance;
// Check if singleton instance is initialized. If it is initialized then we can return the instance.
if (result == null) {
// It is not initialized but we cannot be sure because some other thread might have initialized it
// in the meanwhile. So to make sure we need to lock on an object to get mutual exclusion.
synchronized (ThreadSafeDoubleCheckLocking.class) {
// Again assign the instance to local variable to check if it was initialized by some other thread
// while current thread was blocked to enter the locked zone. If it was initialized then we can
// return the previously created instance just like the previous null check.
result = instance;
if (result == null) {
// The instance is still not initialized so we can safely (no other thread can enter this zone)
// create an instance and make it our singleton instance.
instance = result = new ThreadSafeDoubleCheckLocking();
}
}
}
return result;
}
}
网友评论