package com.test.singleton;
/**
*
* Description:饿汉式单例类,在类初始化时,已经自行实例化
* 这种方式基于classLoder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,
* 在单例模式中大多数都是调用getInstance方法,
* 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。
*
* @author 2016年11月17日上午9:16:32
*/
public class Singleton1 {
// 自身私有实例化
private static Singleton1 singleton1 = new Singleton1();
// 私有的构造方法
private Singleton1() {
}
// 静态工厂方法
public static Singleton1 getInstance() {
return singleton1;
}
}
/**
*
* Description:饿汉式,使用静态代码块来实例化,和上面的方法差不过
* @author
* 2016年11月17日上午10:06:00
*/
class Singleton1_2 {
// 自身私有实例化
private static Singleton1_2 singleton1_2 = null;
static{
singleton1_2 = new Singleton1_2();
}
// 私有的构造方法
private Singleton1_2() {
}
// 静态工厂方法
public Singleton1_2 getInstance() {
return singleton1_2;
}
}
package com.test.singleton;
/**
*
* Description:懒汉式单例类,在类初始化时,已经自行实例化,线程不安全 这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。
*
* @author 2016年11月17日上午9:16:32
*/
public class Singleton2 {
private static Singleton2 singleton2 = null;
// 私有的构造方法
private Singleton2() {
}
// 静态工厂方法
public static Singleton2 getInstance() {
if (singleton2 == null)
singleton2 = new Singleton2();
return singleton2;
}
}
/**
*
* Description:这种写法能够在多线程中很好的工作,而且看起来它也具备很好的 lazy
* loading,但是,遗憾的是,效率很低,99%情况下不需要同步。
*
* @author 2016年11月17日上午10:00:09
*/
class Singleton2_2 {
private static Singleton2_2 singleton2_2 = null;
// 私有的构造方法
private Singleton2_2() {
}
// 静态工厂方法
public static synchronized Singleton2_2 getInstance() {
if (singleton2_2 == null)
singleton2_2 = new Singleton2_2();
return singleton2_2;
}
}
package com.test.singleton;
/**
*
* Description:静态内部类 这种方式同样利用了classLoder的机制来保证初始化instance时只有一个线程
* 这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,
* 只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。
*
* @author 2016年11月17日上午10:13:54
*/
public class Singleton3 {
// 内部类
public static class SingletonHolder {
private static final Singleton3 single = new Singleton3();
}
private Singleton3() {
}
public static final Singleton3 getInstance() {
return SingletonHolder.single;
}
}
package com.test.singleton;
/**
*
* Description:枚举
* 《Effective Java》作者推荐使用的方法,
* 优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
* @author
* 2016年11月17日上午10:21:46
*/
public enum Singleton4 {
single;
public void doSomething(){
}
}
package com.test.singleton;
/**
*
* Description:双重校验锁
* 一旦一个共享变量(类成员变量,类的静态成员变量)被volatile修饰后,就具有了两次语义
* (1)保证不同的线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,
* 这个新值对其他的线程是立即可见的
* (2)禁止指令重排序
* @author
* 2016年11月17日上午10:23:48
*/
public class Singleton5 {
private volatile static Singleton5 single;
private Singleton5(){}
public static Singleton5 getInstance(){
if(single == null){
synchronized(Singleton5.class){
if(single == null){
single = new Singleton5();
}
}
};
return single;
}
public static void main(String[] args) {
Singleton5 s1 = Singleton5.getInstance();
Singleton5 s2 = Singleton5.getInstance();
Singleton5 s3 = Singleton5.getInstance();
System.out.println("s1="+s1);
System.out.println("s2="+s2);
System.out.println("s3="+s3);
/*
*结果
s1=com.test.singleton.Singleton5@659e0bfd
s2=com.test.singleton.Singleton5@659e0bfd
s3=com.test.singleton.Singleton5@659e0bfd
*/
}
}