一、单例模式介绍
Singleton模式是一种建型模式,指某个类采用Singleton模式,则在这类类创建后,只能产生一个实便供外部访问。并且提供一个全局访问点。
全局对象和Singleton模式有本质的区别,因为大量的使用全局对象对影响程序的质量,并且很多语言根本不支持全局变量。并且全局对象方式并不能阻止一个类对实例化多次。
二、单例的特点
1、单例只能有一个实例
2、单例必须自己为自己创建唯一的实例。
3、单例必须为其它对象提供这一唯一实例。
三、单例模式的应用
1、每台计算机可以由若干个打印机,但只能有一个Printer Spooler,避免有两个作业同时输出到打印机。
2、一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键。否则会出现主键重复。
四、单例模式使用注意
1、不要使用单例模式存取全局变量。这违背了单列模式的用意,最好放到对应类的静态成员中。
3、不要将数据库连接做成单例,因为一个系统可能与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放。
五、单例模式的举例
(1)
/* 线程安全 但效率比较低 一开始就要加载类new一个 对象
这是饿汉方式的单例模式*/
public class Singleton1 {
private Singleton1(){
}
private static final Singleton1 instance=new Singleton1();
public static Singleton1 getInstancei(){
return instance;
}
}
(2)
// 饱汉方式的单例模式 但是有多个线程访问时就不是安全的 返回的不是同一个对象
public class Singleton {
private Singleton(){
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
(3)
//虽然是安全的 但是效率非常低在一个时候只有一个线程能访问 同时返回一个对象
public class Singleton2 {
private Singleton2(){
}
private static Singleton2 instance;
public static synchronized Singleton2 getInstance() {
if (instance == null)
instance = new Singleton2();
return instance;
}
}
(4)
/* 线程安全 并且效率高 能有多个线程访问*/
public class Singleton3 {
private static Singleton3 instance;
private Singleton3() {
}
public static Singleton3 getIstance() {
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
(5)登记式
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
转自:http://wenku.baidu.com/view/db5006e981c758f5f61f678d.html?from_page=view&from_mod=download
http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html
Singleton模式是一种建型模式,指某个类采用Singleton模式,则在这类类创建后,只能产生一个实便供外部访问。并且提供一个全局访问点。
全局对象和Singleton模式有本质的区别,因为大量的使用全局对象对影响程序的质量,并且很多语言根本不支持全局变量。并且全局对象方式并不能阻止一个类对实例化多次。
二、单例的特点
1、单例只能有一个实例
2、单例必须自己为自己创建唯一的实例。
3、单例必须为其它对象提供这一唯一实例。
三、单例模式的应用
1、每台计算机可以由若干个打印机,但只能有一个Printer Spooler,避免有两个作业同时输出到打印机。
2、一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键。否则会出现主键重复。
四、单例模式使用注意
1、不要使用单例模式存取全局变量。这违背了单列模式的用意,最好放到对应类的静态成员中。
3、不要将数据库连接做成单例,因为一个系统可能与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放。
五、单例模式的举例
(1)
/* 线程安全 但效率比较低 一开始就要加载类new一个 对象
这是饿汉方式的单例模式*/
public class Singleton1 {
private Singleton1(){
}
private static final Singleton1 instance=new Singleton1();
public static Singleton1 getInstancei(){
return instance;
}
}
(2)
// 饱汉方式的单例模式 但是有多个线程访问时就不是安全的 返回的不是同一个对象
public class Singleton {
private Singleton(){
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
(3)
//虽然是安全的 但是效率非常低在一个时候只有一个线程能访问 同时返回一个对象
public class Singleton2 {
private Singleton2(){
}
private static Singleton2 instance;
public static synchronized Singleton2 getInstance() {
if (instance == null)
instance = new Singleton2();
return instance;
}
}
(4)
/* 线程安全 并且效率高 能有多个线程访问*/
public class Singleton3 {
private static Singleton3 instance;
private Singleton3() {
}
public static Singleton3 getIstance() {
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
(5)登记式
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
转自:http://wenku.baidu.com/view/db5006e981c758f5f61f678d.html?from_page=view&from_mod=download
http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html