单例模式:目的是保证一个类只能有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存
饿汉式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
/**
* 饿汉式
*/
public class Singleton implements Serializable {
private Singleton(){
System.out.println("private Singleton");
}
//给static变量赋值最终会在static静态代码块里执行,java虚拟机会保证线程安全
private static final Singleton INSTANCE=new Singleton();
public static Singleton getInstance(){
return INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
}
//防止反射破坏单例模式:
public class Singleton1 implements Serializable {
/**
* 饿汉式
*/
private Singleton1(){
if(INSTANCE!=null){
throw new RuntimeException("单例对象不能重复创建");
}
}
private static final Singleton1 INSTANCE=new Singleton1();
public static Singleton1 getInstance(){
return INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
public Object readResolve(){
return INSTANCE;
}
}
/**
* 枚举类饿汉式
*/
public enum SingletonByEnum {
INSTANCE;
//枚举类的构造默认是private
SingletonByEnum(){
System.out.println("private SingletonByEnum()");
}
public static SingletonByEnum getInstance(){
return INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
@Override
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
}
懒汉式:在类加载时不初始化,等到第一次被使用时才初始化。
/**
* 懒汉式 DCL
*/
public class Singleton3 implements Serializable {
private Singleton3(){
System.out.println("private Singleton3()");
}
//volatile多线程可见性和有序性,这里主要是解决有序性
//有可能INSTANCE还没有构造完就把对象赋值给了INSTANCE,那这时候调用就会出现很多问题
//因此加上volatile保证已经构造完了在把对象赋值给INSTANCE。
private static volatile Singleton3 INSTANCE=null;
public static Singleton3 getInstance(){
if(INSTANCE==null){
synchronized (Singleton3.class){
if (INSTANCE==null){
INSTANCE=new Singleton3();
}
}
}
return INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
}
/**
* 懒汉式 单例 --内部类
*/
public class Singleton2 implements Serializable {
private Singleton2(){
System.out.println("private Singleton2()");
}
//在静态方法里,会在静态代码块里执行,jdk会保证线程安全
private static class Holder{
static Singleton2 INSTANCE=new Singleton2();
}
public static Singleton2 getInstance(){
return Holder.INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
}
在jdk中哪里使用了单例模式:
gc()方法: 饿汉式单例模式
public static void gc() {
Runtime.getRuntime().gc();
}
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
}
console() 双检索懒汉式:
private static volatile Console cons = null;
/**
* Returns the unique {@link java.io.Console Console} object associated
* with the current Java virtual machine, if any.
*
* @return The system console, if any, otherwise <tt>null</tt>.
*
* @since 1.6
*/
public static Console console() {
Console c;
if ((c=cons) == null) {
synchronized (System.class) {
if((c=cons) == null){
cons=c = SharedSecrets.getJavaIOAccess().console();
}
}
}
return c;
}