一. 单例模式的简单介绍
单例模式是设计模式的一种,设计模式就是在大量的实践中总结的代码结构,编程风格,以及解决问题的思考方式。
所谓的单例模式就是对于某个类只能存在一个对象实例,并且该类只提供一个取得对象实例的方法。如果我们让一个类只产生一个对象,我们首先要设置类的构造器是私有的。这样,在类的外部就没有办法随便造类了。但是在类的内部仍然可以创建对象。因为在类的外部无法获得对象,所以必须让这个类的唯一对象是静态的,这样,在类初始化时就可以跟随着类一起被生成。
二. 单例模式的类型
单例模式有两种类型,懒汉式和饿汉式。
1. 懒汉式
懒汉式的懒体现在啥时候用啥时候造,也就是刚开始为null。
2. 饿汉式
比较饿,饥渴,上来先造对象。
3. 两者的区别
(1)懒汉式比较好一点,延迟去创建对象,饿汉式提前加载号对象,但是一直不用,占用资源,生命周期过长。
(2)饿汉式是线程安全的,天然线程安全,懒汉式在if(instance==null)处可能会出现线程不安全的情况
三. 单例模式的代码
1. 懒汉式
package TestOnly;
public class SingleTonTest {
public static void main(String[] args) {
Lazy instance3 = Lazy.getinstance();
Lazy instance4 = Lazy.getinstance();
System.out.println(instance3 == instance4);
}
}
class Lazy{
//1.私有化类的构造器
private Lazy(){
}
//4.声明为private
//2.声明对象,但是没有new
private static Lazy instance = null;
public static Lazy getinstance(){
if(instance == null){
instance = new Lazy();
}
return instance;
}
}
2. 饿汉式
package TestOnly;
public class SingleTonTest {
public static void main(String[] args) {
Hungry instance1 = Hungry.getintance();
Hungry instance2 = Hungry.getintance();
System.out.println(instance1 == instance2);
}
}
class Hungry{
//1.构造器私有
private Hungry(){
}
//4.声明为static
//2.获得该类的对象声明为私有的
private static Hungry instance = new Hungry();
//3.返回方法
public static Hungry getintance(){
return instance;
}
}
3. 懒汉式线程安全版1
class LazySafe1{
private LazySafe1(){
}
private static LazySafe1 instance = null;
public static synchronized LazySafe1 getinstance(){
if(instance == null){
instance = new LazySafe1();
}
return instance;
}
}
4. 懒汉式线程安全版2
class LazySafe2{
private LazySafe2(){
}
private static LazySafe2 instance = null;
public static LazySafe2 getinstance(){
synchronized(LazySafe2.class){
if(instance == null){
instance = new LazySafe2();
}
return instance;
}
}
}
5. 懒汉式线程安全版快速版
class LazySafe3{
private LazySafe3(){
}
private static LazySafe3 instance = null;
public static LazySafe3 getinstance(){
if(instance == null){
synchronized(LazySafe3.class){
if(instance == null){
instance = new LazySafe3();
}
}
}
return instance;
}
}
6. 三种线程安全版的懒汉式的区别
第一种和第二种是一样的,区别在于用什么方式实现锁,一个是同步代码块,拿类的class充当唯一对象,另外一个是用的同步方法。而四三种方法则是预先判断该对象有没有被创建出来,提前判断,而节省了拿锁排队等待的情况。