单例模式:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
但我们建立了一个简单的单例类后就可以在单例类中对要创建的对象进行自我创建,定向的向外界提供而不允许外界去创建。这样就可以实现对一些对象和资源的身份权限的验证和达到控制资源的目的。利用单例模式生成的对象是唯一的,确保外界多次引用的对象是同一个。对于一些占用资源较多的类有时候会使用单类模式,同时这个类也可能存在并发问题,所以可能会用到多线程进行控制访问。
package com.lcq.factory;
/**
* 单例模式和工厂方法模式
* @author lcq
*
*/
public class Car {
//保证只能返回同一个对象
private static Car car = new Car();
/**
* 将构造函数定义为私有的,不允许外部new
*/
private Car() {
}
/**
* 工厂方法
* @return
*/
public static Car getInstance() {
return car;
}
public void run() {
System.out.println("开车去东北。。。");
}
}
在Test客户类中进行测试:
package com.lcq.factory;
public class Test {
public static void main(String[] args) {
Car car = Car.getInstance();
Car car2 = Car.getInstance();
//得到的car对象是同一个
if (car == car2) {
System.out.println("same car");
}
car.run();
}
}
上面的实例只是使用了new的方法进行对象的创建,同样也可以通过反射构造单例对象,或者通过序列化构造单例对象,但是其最终的用途是相同的。具体用哪种方法去实现可以根据具体情况而定。
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
要点:
确保一个类只有一个实例,并提供一个全局访问点。
1)如何保证是单例,只有一个对象:
类中构造器是私有的,实例化只能类本身的方法调用构造器。
2)提供一个全局的方法获取实例化的单例对象:
使用静态static方法。
3)确保多线程中单例:
使用双重检查加锁。(volatile、synchronized)
单例模式类图: