1.饿汉式(静态常量)
public class SingletonTest01 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
//1.构造器私有化,防止外部new
private Singleton() {
}
//2.本类内部创建对象实例
private final static Singleton instance = new Singleton();
//3.提供一个公有的静态方法返回对象实例
public static Singleton getInstance() {
return instance;
}
}
优点:在类加载的时候就实例化,避免了线程同步的问题
缺点:如果未使用会造成内存浪费
2.饿汉式(静态代码块)
public class SingletonTest02 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
//1.构造器私有化,防止外部new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
//通过静态代码块来创建对象
static {
instance = new Singleton();
}
//3.提供一个公有的静态方法返回对象实例
public static Singleton getInstance() {
return instance;
}
}
优点:在类加载的时候就实例化,避免了线程同步的问题
缺点:如果未使用会造成内存浪费
3.懒汉式(线程不安全)
public class SingletonTest03 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
优点:起到了懒加载的作用,但是只能在单线程下使用
缺点:多线程的时候可能会产生多个实例
4.懒汉式(线程安全,同步方法)
public class SingletonTest04 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
private Singleton() {
}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
优点:在3的基础上解决了线程不安全的问题
缺点:效率太低了
5.懒汉式(线程安全,同步代码块)
public class SingletonTest05 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if(instance==null){
synchronized(Singleton.class){
instance = new Singleton();
}
}
return instance;
}
}
优点:起到了懒加载的作用,但是只能在单线程下使用
缺点:多线程下
进入了
if (singleton == null)
判断语句块还未执行时另一个线程进入,起不到线程同步的作用
6.双重检测锁
public class SingletonTest04 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
private Singleton() {
}
private static volatile Singleton instance;
//加入双重检查代码,解决线程安全的问题同时解决懒加载问题
public static Singleton getInstance() {
if(instance==null){
synchronized(Singleton.class){
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}
}
优点:进行了两次
if (singleton == null)检查保证线程安全。
实例化代码只用执行一次,后面再次访问时,判断
if (singleton == null)
,
直接
return
实例化对象,也避免的反复进行方法同步
7.静态内部类
public class SingletonTest03 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {
private Singleton() {
}
private static volatile Singleton instance;
public static class SingletonInstance{
private static final Singleton INSTANCE=new Singleton();
}
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
优点:避免了线程不安全,利用静态内部类特点实现延迟加载,效率高
8.枚举
public class SingletonTest03 {
public static void main(String[] args) {
//测试
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
enum Singleton {
INSTANCE;
public static Singleton getInstance() {
return INSTANCE;
}
}
优点:避免多线程同步问题,而且还能防止反序列化重新创建新的对象