我以对数据库的连接为例,来实现两种单例模式。
先给出我的配置文件截图:
懒汉模式
上代码(相关代码的注释已经解释地很清楚了):
public class MecOrm {
private static Connection connection;
private MecOrm() { //这里是重点,构造方法是修饰权限是:private
PropertiesParser property = new PropertiesParser();
//这里还是直接用到了前面博文写的工具————properties文件的解析
property.loadProperties("/mecOrm.properties");
String driver = property.getValue("driver");
String url = property.getValue("url");
String user = property.getValue("user");
String password = property.getValue("password");
//很清楚的可以看到,这是mysql数据库的连接部分,需要提供driver,user,url,password
//这里用properties文件的目的是为了,以后可以连接任意数据库,只要修改配置文件即可!!!
//不需要修改代码!!!
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
//懒汉模式
public static Connection getInstance() {
//这里的判断,很显然,如果conncetion为null,就申请一个空间,如果不为null,直接return;
//保证了它的单例性 ,,只有一份!!!
if (connection == null) {
synchronized (MecOrm .class) {//这里加了锁,是为了防止多线程情况
if (connection == null) {
new MecOrm();
}
}
}
return connection;
}
}
上述的用法直接就是:Connection connection = MecOrm.getInstance();
非常简单,用起来很爽,可以发现这里很奇怪,有点像:
Calendar today = Calendar.getInstance();
其实,上面编写的MecOrm这个类,就是一个Calendar的简单实现过程,仅仅是简单的实现过程。
上面的两个技巧就是,1.private来修饰构造方法;2.用if来判断是否为null,如果不为null,就直接返回,如果为null,就申请!!!
饿汉模式
public class MecOrm {
private static Connection connection;
//饿汉模式
static {
// static 静态块中的语句,只在本类第一次被引用时,被调用一次
//这可以保证数据库驱动只启动一次。
PropertiesParser property = new PropertiesParser();
//这里还是直接用到了前面博文写的工具————properties文件的解析
property.loadProperties("/mecOrm.properties");
String driver = property.getValue("driver");
String url = property.getValue("url");
String user = property.getValue("user");
String password = property.getValue("password");
//很清楚的可以看到,这是mysql数据库的连接部分,需要提供driver,user,url,password
//这里用properties文件的目的是为了,以后可以连接任意数据库,只要修改配置文件即可!!!
//不需要修改代码!!!
try {
//在静态块中出现异常,只能“捕获”!
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private MecOrm() {
}
}
JVM对于类的静态块,其处理过程是:当类加载后,程序中第一次出现
1.实例化该类,即,使用new关键字;
2.引用该类的静态成员;
3.引用该类的静态方法;
4.通过反射机制实例化该类、引用该类的静态成员或方法
就会自动执行静态块中的代码,而且,只执行一次!!!这事JVM内部的处理过程,不是我们的代码可以控制的。
而这种对静态块只执行一次的特点,正好可以用来实现线程安全的单例模式!