模式定义
确保一个类最多只有一个实例,并提供一个全局访问点。
单例模式分为饿汉式和懒汉式。
懒汉式单例模式:在类加载时不初始化。
饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
饿汉式-线程安全
/**
* 饿汉式单例模式(线程安全)
*/
public class Singleton {
//static单例变量
private static Singleton singleton = new Singleton();
//私有的构造方法
private Singleton() {
}
//静态方法为调用者提供单例对象
public static Singleton getInstance() {
return singleton;
}
}
懒汉式-线程不安全
/**
* 懒汉式(线程不安全)
*/
public class Singleton2 {
private static Singleton2 instance = null;
private Singleton2() {
}
public static Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
懒汉式-线程安全
/**
* 懒汉式(线程安全)
*/
public class Singleton3 {
private static Singleton3 instance = null;
private Singleton3() {
}
public static synchronized Singleton3 getInstance() {
if (instance == null) {
instance = new Singleton3();
}
return instance;
}
}
双重校验锁-线程安全
/**
* 双重校验锁(线程安全)
*/
public class Singleton4 {
private volatile static Singleton4 instance = null;
private Singleton4() {
}
/**
* 当第一次调用getInstance()方法时,instance为空,同步操作,保证多线程实例唯一
* 当第一次后调用getInstance()方法时,instance不为空,不进入同步代码块,减少了不必要的同步
*/
public static Singleton4 getInstance() {
if (instance == null) {
synchronized (Singleton4.class) {
if (instance == null) {
instance = new Singleton4();
}
}
}
return instance;
}
}
静态内部类-线程安全
/**
* 静态内部类(线程安全)
*/
public class Singleton5 {
/**
* 静态内部类
*/
private static class SingleHolder {
public static Singleton5 instance = new Singleton5();
}
//第一次调用getInstance方法时,才会去加载SingleHolder类,继而实例化instance
public static Singleton5 getInstance() {
return SingleHolder.instance;
}
private Singleton5() {
}
}
静态代码块-线程安全
/**
* 静态代码块(线程安全)
*/
public class Singleton6 {
private Singleton6() {
}
private static Singleton6 instance = null;
// 静态代码块
static {
instance = new Singleton6();
}
public static Singleton6 getInstance() {
return instance;
}
}
枚举-线程安全
/**
* 枚举(线程安全)
*/
public enum Singleton7 {
//枚举实例的创建是线程安全的,任何情况下都是单例(包括反序列化)
INSTANCE;
}
测试各种单例模式的线程安全
package com.wpx.singleton;
public class SingletonDemo implements Runnable {
public static void main(String[] args) {
SingletonDemo[] threads = new SingletonDemo[10];
for (int i = 0; i < threads.length; i++) {
threads[i] = new SingletonDemo();
}
for (int i = 0; i < threads.length; i++) {
new Thread(threads[i]).start();
}
}
@Override
public void run() {
// System.out.println(Singleton.getInstance().hashCode());//饿汉式单例模式(线程安全)
// System.out.println(Singleton2.getInstance().hashCode());//懒汉式(线程不安全)
// System.out.println(Singleton3.getInstance().hashCode());//懒汉式(线程安全)
// System.out.println(Singleton4.getInstance().hashCode());//双重校验锁(线程安全)
// System.out.println(Singleton5.getInstance().hashCode());//静态内部类(线程安全)
// System.out.println(Singleton6.getInstance().hashCode());//静态代码块(线程安全)
System.out.println(Singleton7.INSTANCE.hashCode());//枚举(线程安全)
}
}
java.lang.Runtime中的单例模式(饿汉式-线程安全)
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {
}
}