class Singletom
{
//最差写法。构造方法是public的,有可能会被new出多个,那就不是单例了。
public Singletom(){
}
public static Singletom instance ;
public static void getInstance(){
if(instance==null){
instance= new Singletom();
}
}
}
class Singletom
{
//构造改成私有,基本满足,但多线程时,可能同时在get时是空,同时去new了对象。也出现了多个对象情况。
private Singletom(){
}
private static Singletom instance ;
public static void getInstance(){
if(instance==null){
instance= new Singletom();
}
}
}
class Singletom
{
private Singletom(){
}
private static Singletom instance ;
//针对多线程进行同步,到这儿这个单例基本比较完善了。
public static synchronized void getInstance(){
if(instance==null){
instance= new Singletom();
}
return instance ;
}
}
class Singletom
{
private Singletom(){
}
//双重检查模式
private static Singletom instance ;
public static void getInstance(){
if(instance==null){
synchronized(Singletom.class){
if(instance==null){
instance= new Singletom();
}
}
}
return instance ;
}
}
class Singletom
{
private Singletom(){
}
//加上原子操作,进一步保证多线程安全。
private static volatile Singletom instance ;
public static void getInstance(){
if(instance==null){
synchronized(Singletom.class){
synchronized(Singletom.class){
if(instance==null){
instance= new Singletom();
}
}
} } return instance ; } }
//饿汉式实现
//这种方法比较完美,但是这个类会在载入的时候提前实例化,会浪费空间。
public class SingleB {
private static final SingleB INSTANCE = new SingleB();
private SingleB() {}
public static SingleB getInstance() {
return INSTANCE;
}
}
// Effective Java 第一版推荐写法
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
牛逼之处
对于内部类SingletonHolder,它是一个饿汉式的单例实现,在SingletonHolder初始化的时候会由ClassLoader来保证同步,使INSTANCE是一个真·单例。同时,由于SingletonHolder是一个内部类,只在外部类的Singleton的getInstance()中被使用,所以它被加载的时机也就是在getInstance()方法第一次被调用的时候。
《Effective Java》的作者在这本书的第二版又推荐了另外一种方法,来直接看代码:
复制代码
// Effective Java 第二版推荐写法
public enum SingleInstance {
INSTANCE;
public void fun1() {
// do something
}
}
// 使用
SingleInstance.INSTANCE.fun1();
复制代码
看到了么?这是一个枚举类型……连class都不用了,极简。