Java 常见的几种单例模式 总结

Java的单例模式是Java中最常用的设计模式之一,它主要有两种,一种是懒汉式单例模式,另一种是饿汉式单例模式。另外还有一种单例模式是采用内部类的方法将上面的两种方法相结合。

public class Singletonl {
	private static Singletonl singleton = null;
	private Singletonl(){
	
	}
	public static Singletonl getInstance(){
		if(singleton == null){
		singleton = new Singleton1();
		}
		return singleton;
	}
}

% 懒加载启动快,资源占用小,使用时才实例化,无锁。
% 缺点:非线程安全;


public class Singeleton
{
	private static Singleton instance=null;
	private Singleton(){
	}
	public static synchronized Singleton getInstance(){
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}
}

% 优点同上,
% 缺点: synchronized 为独占排他锁,并发性能差。即使在创建成功以后,获取实例仍然是串行化操作。
% 每次通过getInstance方法得到singleton实例的时候都有一个试图去获取同步锁的过程。而加锁是很耗时的。能避免则避免。

% 懒汉模式--双重加锁检查 Double Check Lock
public class Singleton{
	// 对保存实例的变量添加volatile的修饰
	private volatile static Singleton instance = null;
	private Singleton(){
	}

	public static Singleton getInstance(){
		// 先检查实例是否存在,如果不存在才进入下面的同步块
		if(instance ==null){
			// 同步快,线程安全的创建实例
			synchronized(Singleton.class){
				//再次检查实例是否存在,如果不存在才真的创建实例
				if(instance ==null){
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

% 只有当instance 为null时,需要获取同步锁,创建一次实例,当实例被创建,则无需试图加锁。
% 用双重if判断,复杂容易出错

% 饿汉式 (adivse to use)

public class Singleton{
	public static Singleton instance = new Singleton();
	private Singleton(){
	}
}

public static Singleton getInstance(){
	
	return instance;
}

% 优点:线程安全,使用时没有延迟
% 缺点:启动时即创建实例,启动慢,有可能造成资源浪费。没有懒式加载的按需创建效果,降低了内存的使用率

% 静态内部类
public class Singleton{
	
	private Singleton(){
	
	}
	private static class SingletonHolder{
		private static Singleton instance = new Singleton();

	}
	public static Singleton getInstance(){
		return SingletonHolder.instance;
	}
}

% 将懒加载和线程安全完美结合的一种方式(无锁),实现了按需创建实例的效果
% 定义一个私有的内部类,在第一次用该内部类时,会创建一个实例。而类型为SingletonHolder的类,
% 只有在Singleton.getInstance()中调用,由于私有的属性,他人无法使用SingleHolder, 不调用 
% Singleton.getInstance()就不会创建实例。

单例模式的特点是:

1. 全局共享,独一份;其次, 构造函数不暴露(如果暴露便不能保证一份),自己负责自己的构造;

2. 懒汉式:Lazy load,用到才加载,非线程安全。如何保证线程安全呢:

(1) synchronized getInstance()。

(2)双重检查加锁(volatile)。

3. 饿汉式:一开始就申请好,浪费了点资源,但其线程安全。

4. Holder模式(采用静态内部类):

(1)改成内部类,由JVM保证线程安全性。

参考: https://www.cnblogs.com/t0000/p/8250686.html

 

 

发布了39 篇原创文章 · 获赞 41 · 访问量 12万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览