Java设计模式(一)单例模式

单例模式(Singleton)是Java中最简单的设计模式之一。属于创建模式。这种模式涉及一个类,他负责创建一个对象实例,同时确保只创建一个对象实例,
这个类提供了一种方法来访问它的唯一对象,可以直接访问,而不需要实例化类的对象。
package sword2offer; class Singleton1 { /** * 一、懒汉模式 * 达到了lazy loading的效果,但是不保证线程安全,并发环境下可能会产生多个Singleton实例 */ private static Singleton1 instance ; private Singleton1() {} public static Singleton1 getInstance(){ if (instance == null) { instance = new Singleton1() ; } return instance ; } } class Singleton2 { /** * 二、懒汉模式(变种) * 达到了lazy loading的效果,线程安全,但是每次都需要同步,明显效率低下 */ private static Singleton2 instance ; private Singleton2(){} public static synchronized Singleton2 getInstance(){ if (instance == null) { instance = new Singleton2() ; } return instance ; } } class Singleton3 { /** * 三、饿汉模式 * 类在装载的时候就实例化,没有达到lazy loading的效果 ,但是线程安全。 * 基于classloder机制避免了多线程的同步问题。 */ private static Singleton3 instance = new Singleton3() ; private Singleton3() {} public Singleton3 getInstance(){ return instance ; } } class Singleton4 { /** * 四、饿汉模式(变种) * 只是加了一个静态代码块,与三相同 */ private static Singleton4 instance = null ; static { instance = new Singleton4() ; } private Singleton4() {} public static Singleton4 getInstance(){ return instance ; } } class Singleton5 { /** * 五、静态内部类 * 利用了classloder的机制来保证初始化instance时只有一个线程, * 这种方式是Singleton类被装载了,instance不一定被初始化。 * 因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时, * 才会显示装载SingletonHolder类,从而实例化instance。 */ private Singleton5() {} private static class T { private static Singleton5 t = new Singleton5() ; } public static Singleton5 getInstance(){ return T.t ; } } class Singleton6 { /** * 六、双重校验锁 * 考虑这样一种情况,就是有两个线程同时到达,即同时调用 getInstance() 方法,此时由于single == null ,所以很明显,
    两个线程都可以通过第一重的 singleTon == null ,进入第一重 if 语句后,由于存在锁机制,所以会有一个线程进入 lock
    语句并进入第二重 singleTon == null ,而另外的一个线程则会在 lock 语句的外面等待。而当第一个线程执行完
    new SingleTon()语句后,便会退出锁定区域,此时,第二个线程便可以进入 lock 语句块,此时,如果没有第二重
    singleTon == null 的话,那么第二个线程还是可以调用 new SingleTon()语句,这样第二个线程也会创建一个
    SingleTon 实例,这样也还是违背了单例模式的初衷的。使用volatile可以禁止指令重排序。
*/ private static volatile Singleton6 instance = null ; private Singleton6() {} public static Singleton6 getInstance() { if (instance == null) { synchronized(Singleton6.class){ if (instance == null) { instance = new Singleton6() ; } } } return instance ; } }

 

单例模式(Singleton)是Java中最简单的设计模式之一。属于创建模式。这种模式涉及一个类,他负责创建一个对象实例,同时确保只创建一个对象实例,这个类提供了一种方法来访问它的唯一对象,可以直接访问,而不需要实例化类的对象。

package sword2offer;

 

class Singleton1 {

/**

 *  一、懒汉模式

 *  达到了lazy loading的效果,但是不保证线程安全并发环境下可能会产生多个Singleton实例

 */

private static Singleton1 instance ;

private Singleton1() {}

public static Singleton1 getInstance(){

if (instance == null) {

instance = new Singleton1() ;

}

return instance ;

}

 

}

 

class Singleton2 {

/**

 *  二、懒汉模式(变种)

 *  达到了lazy loading的效果,线程安全,但是每次都需要同步,明显效率低下

 */

private static Singleton2 instance ;

private Singleton2(){}

public static synchronized Singleton2 getInstance(){

if (instance == null) {

instance = new Singleton2() ;

}

return instance ;

}

}

 

class Singleton3 {

/**

 * 三、饿汉模式

 * 类在装载的时候就实例化,没有达到lazy loading的效果 ,但是线程安全。

 * 基于classloder机制避免了多线程的同步问题。

 */

private static Singleton3 instance = new Singleton3() ;

private Singleton3() {}

public Singleton3 getInstance(){

return instance ;

}

}

 

class Singleton4 {

/**

 * 四、饿汉模式(变种)

 * 只是加了一个静态代码块,与三相同

 */

private static Singleton4 instance = null ;

static {

instance = new Singleton4() ;

}

private Singleton4() {}

public static Singleton4 getInstance(){

return instance ;

}

}

 

class Singleton5 {

/**

 * 五、静态内部类

 * 利用了classloder的机制来保证初始化instance时只有一个线程,

 * 这种方式是Singleton类被装载了,instance不一定被初始化。

 * 因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,

 * 才会显示装载SingletonHolder类,从而实例化instance

 */

private Singleton5() {}

private static class T {

private static Singleton5 t = new Singleton5() ;

}

public static Singleton5 getInstance(){

return T.t ;

}

}

 

class Singleton6 {

/**

 * 六、双重校验锁

 * 考虑这样一种情况,就是有两个线程同时到达,即同时调用 getInstance() 方法,此时由于single == null ,所以很明显,两个线程都可以通过第一重的 singleTon == null ,进入第一重 if 语句后,由于存在锁机制,所以会有一个线程进入 lock 语句并进入第二重 singleTon == null ,而另外的一个线程则会在 lock 语句的外面等待。而当第一个线程执行完 new SingleTon()语句后,便会退出锁定区域,此时,第二个线程便可以进入 lock 语句块,此时,如果没有第二重 singleTon == null 的话,那么第二个线程还是可以调用 new SingleTon()语句,这样第二个线程也会创建一个 SingleTon 实例,这样也还是违背了单例模式的初衷的。

使用volatile可以禁止指令重排序。 

*/

private static volatile Singleton6 instance = null ;

private Singleton6() {}

public static Singleton6 getInstance() {

if (instance == null) {

synchronized(Singleton6.class){

if (instance == null) {

instance = new Singleton6() ;

}

}

}

return instance ;

}

}

posted @ 2017-10-19 16:36  落下树的汪汪狗  阅读(151)  评论(0编辑  收藏  举报