介绍:
Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。
全局对象和Singleton模式有本质的区别,因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本不支持全局变量。最重要的是传统的全局对象并不能阻止一个类被实例化多次。
特点:
单例类只可有一个实例。
单例类必须自己创建自己这惟一的实例。
单例类必须给所有其他对象提供这一实例。
虽然单例模式中的单例类被限定只能有一个实例,但是单例模式和单例类可以很轻易被推广到任意且有限多个实例的情况,这时候称它为多例模式(Multiton Pattern) 和多例类(Multiton Class)
应用:
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
举例:
懒汉模式:
package singleton;
/*
* 懒汉模式
*/
public class Singleton_1 {
private static Singleton_1 singleton_1 = null;
private Singleton_1(){
System.out.println("进入懒汉模式调用");
}
public static Singleton_1 getInfo(){
if(singleton_1 == null){
System.out.println("进入懒汉模式创建实例");
singleton_1 = new Singleton_1();
}else{
System.out.println("懒汉模式调用");
}
return singleton_1;
}
}
package singleton;
/*
* 懒汉模式
*/
public class Singleton_2 {
public static void main(String[] args) {
myprint();
}
public static void myprint(){
Singleton_1 s1 = Singleton_1.getInfo();
Singleton_1 s2 = Singleton_1.getInfo();
if(s1 == s2){
System.out.println("---同一实例---");
}
}
}
以上懒汉模式并不安全,要实现线程安全:
1、在getInstance方法上加同步
public static synchronized Singleton_1 getInfo(){
if(singleton_1 == null){
System.out.println("进入懒汉模式创建实例");
singleton_1 = new Singleton_1();
}else{
System.out.println("懒汉模式调用");
}
return singleton_1;
}
2、双重检查锁定
public static Singleton_1 getInfo(){
if(singleton_1 == null){
synchronized (Singleton_1.class) {
if(singleton_1 == null){
System.out.println("进入懒汉模式创建实例");
singleton_1 = new Singleton_1();
}
}
}else{
System.out.println("懒汉模式调用");
}
return singleton_1;
}
3、静态内部类
private static class Test{
private static final Singleton_1 singleton = new Singleton_1();
}
public static final Singleton_1 getInfo(){
return Test.singleton;
}
这种比上面1、2都好一些,既实现了线程安全,又避免了同步带来的性能影响。
饿汉模式:
package singleton;
/*
* 饿汉模式
*/
public class Singleton_3 {
private static Singleton_3 singleton = new Singleton_3();//创建一个静态实例
private Singleton_3(){
System.out.println("进入懒汉模式调用");
}
public static Singleton_3 getInfo(){
System.out.println("懒汉模式调用");
return singleton;
}
}
package singleton;
/*
* 饿汉模式
*/
public class Singleton_4 {
public static void main(String[] args) {
print();
}
public static void print(){
Singleton_3 s1 = Singleton_3.getInfo();
Singleton_3 s2 = Singleton_3.getInfo();
if(s1 == s2){
System.out.println("---同一实例---");
}
}
}