单例模式的定义与特点
单例模式的定义:
指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如:windows中只能打开一个任务管理器,这样能避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示的内容 的不一致的错误。
在计算机系统中还有windows的回收站,操作系统中的文件系统,多线程中的线程池,网站的计数器,web应用的配置对象,应用程序中的对话框,系统中的缓存等常常 被设计成单例
单例模式有三个特点:
单例类只有一个实例对象;
该单例对象必须由单例类自行创建;
单例类对外提供一个访问该单例的全局访问点;
单例模式的结构与实现:
单例模式是设计模式中最简单的模式之一,通常,普通类的构造函数是共有的,外部类可以通过 “new 构造函数” 来生成多个实例 ,但是,如果将类的构造函数设为私有的,外部类就无法调用该构造函数,也就无法生成多个实例。这时,该类自身必须定义一个静态私有实例,并向外提供一个静态的公有函数用于创建或获取该静态私有实例。
下面来分析其基本结构和实现方法:
单例模式的主要角色如下:
单例类:包含一个实例且能自行创建这个实例的类。
访问类:使用单例的类。
其结构如图所示
单例模式的实现
Singleton 模式通常有两种实现形式:
第一种:懒汉式单例
该模式的特点是类加载时没有生成单例,只有第一次调用getinstance方法时才去创建这个单例。代码如下:
public classLazySingleton{
//被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象
public class Lazysingletion {
private static volatile Lazysingletion instance=null;//保证instancez在所有线程中同步
private LazySingleton(){}//private 避免类在外部被实例化
public static synchronized Lazysingletion getlnstance(){
//getlnstance 方法前加同步
if(instance==null){
instance=new Lazysingletion();
}return instance;
}
}
注意:如果编写的是多线程程序 ,则不要删除上例代码中的关键字volatile和synchronized,否则将存在线程非安全问题,如果不删除这两个关键字就能保证线程安全但是 每次访问时都要同步 ,会影响性能,且消耗更多资源。这是懒汉式单例的缺点。
第二种:饿汉式单例
该模式的特点是 类一旦加载就创建一个单例,保证在调用getinstance方法前单例已经存在了
public class HungrySingleton{
private static final HungrySingleton instance =new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getinstance(){
}
return instance
}
}
饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线性而不会出现问题