单例 是最为最常见的设计模式之一。对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例。例如,对于 class Mouse (不是动物的mouse哦),我们应将其设计为 singleton 模式。
你的任务是设计一个 getInstance
方法,对于给定的类,每次调用 getInstance
时,都可得到同一个实例。
例1:
在 Java 中:
A a = A.getInstance();
A b = A.getInstance();
a 应等于 b.
一般程序设计中单例模式的实现有两类:
如果单例模式实例在系统中经常被用到,可以选择饿汉式,并且它实现起来较为简单;如果单例模式实例在程序中很少用到,就选择懒汉式。
class Solution {
/**
* @return: The same instance of this class every time
*/
private final static Solution INSTANCE = new Solution();
private Solution(){};
public static Solution getInstance(){
return INSTANCE;
}
}
写法简单,在类装载的时候完成实例化,避免了线程同步问题,但是不是懒加载。如果没有使用到该实例,就会造成内存的浪费。
class Solution {
/**
* @return: The same instance of this class every time
*/
static{
instance = new Solution();
}
private Solution(){}
public static Solution getInstance(){
return instance;
}
}
和解法一一样,只不过将类实例化的过程放在了静态代码块,同样在类加载的时候执行静态代码块中的代码。
class Solution {
/**
* @return: The same instance of this class every time
*/
private static Solution instance;
private Solution(){}
public static Solution getInstance(){
if(instance == null){
instance = new Solution();
}
return instance;
}
}
懒加载,但是在多线程环境下,一个线程计入了if判断句,还往下执行,另一个线程也通过了这个判断语句,会产生多个实例。因此只能在单线程环境下使用这中方式。
class Solution {
/**
* @return: The same instance of this class every time
*/
private static Solution instance;
private Solution(){}
public static synchronized Solution getInstance(){
if(instance == null){
instance = new Solution();
}
return instance;
}
}
用synchronized关键字修饰,将getInstance方法变成线程安全的方法。但是这样在每个线程需要获取实例的时候都要进行同步,如果用到该实例的次数很多,这种写法同步效率很低。
class Solution {
/**
* @return: The same instance of this class every time
*/
private static Solution instance;
private Solution(){}
public static Solution getInstance(){
if(instance == null){
synchronized (Solution.class) {
instance = new Solution();
}
}
return instance;
}
}
根据解法四改进,但是如果创建实例的时候,多个线程同时进入if判断这句话,也会创建多个实例,因此并不能完全保证线程安全。
class Solution {
/**
* @return: The same instance of this class every time
*/
private static volatile Solution instance;
private Solution(){}
public static Solution getInstance() {
if(instance == null){
synchronized (Solution.class) {
if(instance == null){
instance = new Solution();
}
}
}
return instance;
}
};
线程安全,懒加载,效率高。
class Solution {
/**
* @return: The same instance of this class every time
*/
private Solution(){}
private static class SolutionInstance {
private static final Solution instance = new Solution();
}
public static Solution getInstance() {
return SolutionInstance.instance;
}
};