单例模式详解
Posted 3 ERROR(s)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式详解相关的知识,希望对你有一定的参考价值。
文章目录
前言
一、单例模式的特点?
单例模式是一种常见的设计模式,它有以下特点:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,总之,选择单例模式就是为了避免不一致状态
二、饿汉式单例模式
class Singleton
//让构造方法变为私有的,在类的外部无法创建对象
private Singleton()
private static Singleton singleDog=new Singleton();
public static Singleton getSingleDog()
return singleDog;
饿汉式在类加载的时候就创建好了一个静态的对象提供使用,以后不再改变,所以它天生就是线程安全的。
三、懒汉式单例模式
1.懒汉模式的创建
相比于饿汉模式,懒汉模式只创建我们需要的实例资源,所以他的效率更高!
class Singleton2
private Singleton2()
private static Singleton2 singleton=null;
public static Singleton2 getSingleton()
if(singleton==null)
Singleton2 singleton=new Singleton2();
return singleton;
2.懒汉模式的线程不安全问题及解决
懒汉模式线程不安全的原因:
- 懒汉式单例模式是线程不安全的,他有可能同时生成多个singleton对象。
- 但是他只有在生成实例对象之前调用getSingleton方法存在线程安全问题。
- 但是如果实例已经创建好了再去并发调用getSingleton就不会出现线程安全问题。
解决线程不安全问题的几种方法:
方式一:加对象锁
class Singleton2
private Singleton2()
private static Singleton2 singleton=null;
public static Singleton2 getSingleton()
synchronized (Singleton2.class)
if(singleton==null)
Singleton2 singleton=new Singleton2();
return singleton;
给getSinglenton方法加上对象锁,保证其原子性。
但是这种加锁方式再创建了实例对象之后还会每次加锁解锁操作,浪费了大量的资源!这时候我们就需要更新一下技术了!
方式二:双重检查锁定
class Singleton2
private Singleton2()
//加入volatile关键字避免内存可见性引来的问题
private volatile static Singleton2 singleton=null;
public static Singleton2 getSingleton()
if (singleton==null) //多加了一个if判定保证效率!
synchronized (Singleton2.class)
if(singleton==null)
Singleton2 singleton=new Singleton2();
return singleton;
方式三: 静态内部类
public class Lazysingleton
//静态内部类
private static class LazyHolder
private static Lazysingleton instance=new Lazysingleton();
private Lazysingleton()
//在类加载的时候只创建了一个instance对象,在调用get方法的时候获得该对象。
public static Lazysingleton getInstance()
return LazyHolder.instance;
既解决了线程安全问题,又解决了浪费资源的问题。
以上是关于单例模式详解的主要内容,如果未能解决你的问题,请参考以下文章