本文介绍了单例模式+工厂模式的具体实现。
单例模式
单例模式(Single Pattern)最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”
特点:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
Java中简单的单例模式(不牵扯并发)注:这个是预加载,如果懒加载的话可以直接声明变量的时候创建对象。
1 | /** |
上面的那种方法是线程不安全的,如果并发则会创建多个对象,下面可以用一个demo测试以下:
1 | public static void main(String[] args) { |
创建两个线程,线程里面分别创建对象。执行结果:

会出现两个对象。这样就不符合我们的单例模式只有一个实例的思想了。
多线程有一个锁机制。使用synchronized修饰。我们可以锁住获取对象的方法。代码如下:
1 | /** |
然后下面我们创建的对象就只有一个实例了。每次获取的都是一个实例。
众所周知线程安全就等于效率会相对低点。所有经过改造优化,出现另一种双重判断方式。代码如下:
1 | /** |
单例模式重点就一个对象,这样理论上会是创建次数少获取的次数多。所以,我们只需加锁创建对象的方式,而判断是否为null,可以不加锁。可以提高效率。
如果按前面一种方式,如果高并发10个线程同时访问,则需要耗费10*(等待时间+判断时间),
而如果用第二张方式,如果通用10个线程访问,则只需10*(判断时间),如果没有对象则再加上一次判断时间和创建对象的时间。
如果去掉锁里面的判断:
1 | public static SinglePattern getInstance() { |
执行结果为:

还是两个实例,为什么呢?
这是因为刚开始instance实例肯定是null的,T1和T2线程里面都是空实例,所以都过了if判断,T1争取到锁了,进去创建了个对象出去了。这个时候因为T2已经通过判断,到达创建对象锁门口了,等T1归还了锁之后,T2线程再进去创建了对象再出去。所以两个线程就创建了两个对象。
所以还要在锁里面判断对象是否为空。
工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
把对象比作产品,创建对象的地方叫做工厂,如:Spring中的Bean和容器。
简单工厂模式 ,代码实现:
一个抽象类水,和三个子类,农夫三拳,哇哈哈,百岁山类。
1 | /** |
然后创建了个工厂存放我的水。进行销售:
1 | class WaterFactory{ |
然后写测试类:
1 | public static void main(String[] args) { |
运行结果为:

这就是简单的工厂模式。也叫静态工厂。
利用反射创建工厂对象
把上面的例子换成基于反射来实现的例子,代码如下:
1 | class ReflexFactory { |
然后把Demo的工厂换做反射工厂。代码如下:
1 | Water water = null; |
还有多种创建工厂的方法。
比如多方法工厂模式,需要什么调什么
1 | //多方法工厂模式,需要什么就调什么 |
java源码的工厂模式:
例如线程池,都知道创建线程池子的方法有很多,其中有一种为创建固定数量的线程池方法:
1 | /**创建具一个可重用的,有固定数量的线程池 |