这篇文章主要讲述基于Java语言实现多线程的单例模式。java
对于一个软件系统中的某些类而言,只有一个实例很重要,例如一个系统只能有一个窗口管理器或文件系统,一个系统只能有一个集市工具或ID生成器等等。在Windows操做系统中就只能打开一个任务管理器窗口,以下图1所示。若是不使用机智对窗口对象进行惟一化,势必会弹出多个窗口。若是这些窗口显示的内容彻底一致,则是重复对象,浪费内存资源;若是这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符合,这会给用户带来误解,不知道哪个才是真实的状态。所以有时确保系统中某个对象的惟一性(即一个类只能有一个实例)很是重要。多线程
确保一个类只有一个实例,并提供一个全局访问点来访问这个惟一实例。工具
实例代码spa
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
if(s1 == s2){
System.out.println("两个对象是相同实例");
}
else{
System.out.println("两个对象是不一样实例");
}
}
}
复制代码
运行截图以下图2操作系统
实例代码线程
public class Singleton {
private Singleton() {
}
//静态内部类
private static class SingletonHandler {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHandler.instance;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
System.out.println("两个对象实例是否相同?");
System.out.println(s1 == s2);
}
}
复制代码
运行截图以下图3code
饿汉式单例类在类加载时就将本身实例化,它的优势在于无需考虑多个线程同时访问的问题,能够确保实例的惟一性;从调用速度和反应时间速度来说,因为单例对象一开始就得以建立,所以要优于懒汉式单例。可是不管系统在运行时是否须要使用该单例对象,因为在类加载时该对象就须要建立,所以从资源利用效率角度来说饿汉式单例不及懒汉式单例,并且在系统加载时因为须要建立饿汉式单例对象,加载时间可能会比较长。cdn
懒汉式单例类在第一次使用时建立,无须一直占用系统资源,实现了延迟加载,可是必需要处理多个线程同时访问的问题,特别是当单例类做为资源控制器,在实例化时必然涉及资源初始化,而资源初始化颇有可能耗费大量时间,这意味着出现多线程同时首次引用此类的概率比较大,须要经过同步化机制进行控制。对象
单例模式的主要优势在于提供了对惟一实例的受控访问并能够节约系统资源;其主要缺点在于由于缺乏抽象层而难以扩展,且单例类职责太重。blog
单例模式适用状况包括:系统只须要一个实例对象;客户调用类的单个实例只容许使用一个公共访问点。