不起眼的文章
生几个我决定!
原本一个类需要生多少个,会受外界的影响(创建多少个实例),并且各个长得都不一样(实例对象的地址都不相同)
而现在我不一样了!现在这种环境下压力大,我自己决定生几个(就创建一个实例)。这种模式就是单列模式!
这就是单列模式?
首先,就是禁止受外界影响(私有的构造方法)
其次,自己生,并且让外界知道自己的孩子(由自己创建实例对象,提供静态方法给外界访问)
提一嘴:虽然实例是唯一的,但是有可以有子类来继承。
但是,好像有个问题吧?
如果外界是一个一个的影响我(单线程),我可以控制得住,但如果出现了一大批人同时来影响我(多线程),我又该如何,或许我会乱成一团糟...(创建了不止一个实例)
解决多线程访问问题
那就是加锁!synchronized
装了一道门(加锁),外界只能一个一个的来访问我。
但是,好像还是有个问题吧? 如果外界并不都是来影响我的,而是只是单纯访问我,那我岂不是降低了访问我的效率吗?(影响了性能)
那我就再优化(双重锁定)
我们并不将外界访问时都加锁(不锁住每个线程),而是将影响我的才加锁(当还未创建实例对象时,只有一个线程访问,然后创建了实例对象,接着其它线程访问的都是已经创建好的实例对象)。
你可能会问:为什么要进行两次 if (singleton == null) 的判断呢?
是这样的,你想想比如有两个线程 A-线程、B-线程:
两个线程同时经过了第一道 if (singleton == null) 判断。
接下来就是要经历锁,只会有一个线程获取锁,假设是 A-线程 获取了锁。
A-线程,创建了实例对象,..........,最终释放了锁。
B-线程 获取了锁,这时候如果没有进行第二道 if (singleton == null) 判断,就会造成再次创建实例对象。
不同生育方式(懒汉式、饿汉式)
上面讲的单列模式就是懒汉式,只有在线程通知我的时候我再去生育,也影响了性能。(被引用的时候,自己才会去实例化对象)
而饿汉式,是我主动生育,不需要其他人来通知,只需要他们来访问。(使用静态初始化的方式,当类被加载的时候就已经实例化对象了)
