单例模式
今天看了一下单例模式,收获颇丰,以前都只是马虎地学一下,现在总结一下以便以后复习。
单例模式要满足一下条件:
1)拥有私有的构造方法,确保用户无法通过new直接实例它
2)拥有静态公有方法,以确保有一个实例被创建
3)一个静态的变量用来保存单实例的引用
下面是我总结的3种方式:
1)饿汉式
1 package com.tomwills.singleton; 2 3 /** 4 * 单例模式1--饿汉式 5 * @author-tomwills:2013-7-22 6 * 7 */ 8 9 public class SingletonTest 10 { 11 public static void main(String[] args) 12 { 13 Singleton singleton = Singleton.getInstance(); 14 Singleton singleton2 = Singleton.getInstance(); 15 System.out.println(singleton == singleton2); 16 17 } 18 } 19 class Singleton 20 { 21 /* 22 * 一个静态的变量用来保存单实例的引用 23 * static是为了让getInstance()可以访问 24 * 静态方法只能访问静态变量 25 */ 26 private static Singleton single = new Singleton(); 27 28 /* 29 * 拥有私有的构造方法,确保用户无法通过new直接实例它 30 */ 31 private Singleton(){ 32 33 } 34 35 /* 36 * 拥有静态公有方法,以确保有一个实例被创建 37 * static保证了外部类可以通过类名直接调用该方法 38 */ 39 public static Singleton getInstance() 40 { 41 return single; 42 } 43 }
2)懒汉式
1 package com.tomwills.singleton; 2 3 /** 4 * 单例模式2 懒汉式--线程安全,但效率低, 5 * 因为很多情况下不需要线程同步 6 * 7 * @author-tomwills:2013-7-22 8 */ 9 10 public class SingletonTest2 { 11 12 public static void main(String[] args) { 13 Singleton2 s = Singleton2.getInstance(); 14 Singleton2 s2 = Singleton2.getInstance(); 15 System.out.println(s == s2); 16 } 17 } 18 19 class Singleton2 { 20 private static Object object = new Object(); 21 private static Singleton2 instance; 22 23 private Singleton2 (){ 24 25 } 26 27 /* 28 * synchronized关键字 29 * 保证在同一时刻最多只有一个线程执行该段代码(线程安全) 30 * 31 * synchronized代码块 32 * 只会将块中代码同步,块外的可以被多个线程访问,提高开发效率 33 * 若没有synchronized代码块,则线程不安全 34 */ 35 public static Singleton2 getInstance() { 36 synchronized(object){ 37 if (instance == null) { 38 instance = new Singleton2(); 39 } 40 return instance; 41 } 42 } 43 }
3)双重校验锁
1 package com.tomwills.singleton; 2 3 /** 4 * 单例模式3 双重校验锁(Double-Checked Locking) 5 * 是懒汉式的升级版 6 * 7 * @author-tomwills:2013-7-22 8 */ 9 10 public class SingletonTest3 { 11 12 public static void main(String[] args) { 13 Singleton3 s = Singleton3.getInstance(); 14 Singleton3 s2 = Singleton3.getInstance(); 15 System.out.println(s == s2); 16 } 17 } 18 19 class Singleton3 { 20 21 private static Singleton3 instance; 22 23 private Singleton3 (){ 24 25 } 26 27 /* 28 * 先判断实例是否为空再加锁,而不用让线程每次都加锁 29 */ 30 public static Singleton3 getInstance() { 31 if (instance == null) { 32 synchronized(Singleton3.class){ 33 instance = new Singleton3(); 34 } 35 } 36 return instance; 37 } 38 }
测试结果皆为:true