Java设计模式の单利模式

  单利模式:确保一个类最多只有一个实例,并提供一个全局访问点

  经典单利模式创建对象代码  

public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton(){ }
public static Singleton getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Singleton();
}
return uniqueInstance;
}
}

  问题:多线程

public class Q {
//多线程
private static Q uniqueInstance = null;
private Q(){ }
public static Q getInstance(){
if (uniqueInstance==null) {//当线程1执行此语句后,判断通过,
/*正准备执行uniqueInstance=new Q()时,线程2抢占到了cpu资源,
*切换到线程2开始执行,线程2会发现uniqueInstance还是null,所以会创建对象,创建完后,
*而当切换到线程1时,发现线程1已经进入if判断,所以也会创建一个新uniqueInstance,
*此时线程1创建的uniqueInstance和线程2创建的uniqueInstanc是不一样的
**/
uniqueInstance=new Q();
}
return uniqueInstance;
}
}

  解决办法

  1、创建对象的方法加同步锁

/**
* 优化方式1
* 方法添加同步锁
* 优点:使用方便
* 缺点:当线程很多的情况下,非常耗费资源
* @author yxm
*
*/
public class Optimization_Singleton_1 {
private static Optimization_Singleton_1 uniqueInstance = null;
private Optimization_Singleton_1(){ }
public synchronized static Optimization_Singleton_1 getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_1();
}
return uniqueInstance;
}
}

  2、饿汉式创建对象

/**
* 优化方式2
* 急切创建对象
* 优点:不会因为加锁而耗费资源
* 缺点:当不使用此类时,照样会耗费内存
* @author yxm
*
*/
public class Optimization_Singleton_2 {
private static Optimization_Singleton_2 uniqueInstance = new Optimization_Singleton_2();
private Optimization_Singleton_2(){ }
public static Optimization_Singleton_2 getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_2();
}
return uniqueInstance;
}
}

  3、双重检查加锁 (较完美)

/**
* 优化方式3
* 双重检查加锁
* 较完美
* @author yxm
*
*/
public class Optimization_Singleton_3 {
private volatile static Optimization_Singleton_3 uniqueInstance = null;//volatile给编译器使用,保证线程安全
private Optimization_Singleton_3(){ }
public synchronized static Optimization_Singleton_3 getInstance(){
if (uniqueInstance==null) {
       //只有等线程1把对象创建好了,其他线程才会进入以下代码块
synchronized(Optimization_Singleton_3.class){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_3();
}
}
}
return uniqueInstance;
}
}

  案例:一个巧克力工厂,生产各式各样的巧克力,生产过程有(准备原料、填充、加热、排出)四道工序,但是现在工厂里只有一条生产线,意味着一次只能生产一种巧克力,请问如何把控?

  分析:转换为计算机思维,此场景是典型的一个类只能有一个对象,符合单利模式特征

  普通巧克力工厂

public class ChocolateFactory {
private boolean empty;
private boolean boiled; public ChocolateFactory(){
empty=true;
boiled=false;
}
//填充
public void fill(){
if (empty) {
empty=false;
boiled=false;
}
}
//加热
public void boil(){
if (!boiled) {
boiled=true;
}
}
//排出
public void drain(){
if (!empty&&boiled) {
empty=true;
}
}
}

  使用单利模式后的巧克力工厂

public class ChocolateFactoryInSingleton {
private boolean empty;
private boolean boiled;
public static ChocolateFactoryInSingleton uniqueInstance=null;
private ChocolateFactoryInSingleton(){
empty=true;
boiled=false;
}
public static ChocolateFactoryInSingleton getInstance(){
     //此处确保不同的巧克力不会进入同一条生产线
if (uniqueInstance==null) {
uniqueInstance=new ChocolateFactoryInSingleton();
}
return uniqueInstance;
}
//填充
public void fill(){
if (empty) {
empty=false;
boiled=false;
}
}
//加热
public void boil(){
if (!boiled) {
boiled=true;
}
}
//排出
public void drain(){
if (!empty&&boiled) {
empty=true;
}
}
}
上一篇:如何购买阿里云等产品---附上阿里云产品购买地址


下一篇:阿里云物联网平台OTA升级平台侧常见问题