单利设计模式:保证了内存中只有一个对象,例如在配置数据源,和连接池的时保证链接不浪费掉,可以只new出一个connection,如果一个用户的connection释放掉后,就放到连接池中,保证这个对象不被浪费掉,本文现只关注单例的实现。
单例模式一般分为:懒汉式和饿汉式模式,这两种模式的根本区别是,当用到此对象时,是否提前创建此对象,还是延迟创建对象的时机,在线程安全方面,饿汉式是线程安全 的,懒汉式如果控制不好的话会有线程安全问题。原理我们下面分析
饿汉式模式:
<pre class="java" name="code">package cn.single.example;
import java.sql.Connection;
import java.sql.DriverManager;
public class Single {
private static Single single=new Single();
private static Connection connection;
private static String url="jdbc:mysql://localhost:3306/test";
private static String username="root";
private static String password="admin";
private Single(){}
static{
try {
Class.forName("com.mysql.jdbc.Driver");
//懒汉式设计思想,在拿之前new出connection
connection = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//返回single对象,我们拿到single对象后拿connection就很方便了
public static Single getSingle(){
return single;
}
//也可以直接拿Connection
public static Connection getConnection(){
return connection ;
}
}
测试类:
package cn.single.example;
public class SingleTest {
public static void main(String[] args) {
Single single1= Single.getSingle();
Single single2= Single.getSingle();
System.out.println(single1==single2);
}
}
打印的true;这就保证了内存中能只有这一个对象,那么他拿出来的connection也是同一个链接
这就是饿汉式模式:
1.构造方法私有化
2.获取实例的方法static
3.提前new出对象
懒汉式模式:事先不会去new出对象,当我们用的时候在去new出对象,给出去。
1.构造方法私有化
2.获取实例的方法static
3.不去new对象,在获取实例的new对象
package com;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class HungrySinge {
private static HungrySinge single=null;
private static Connection connection;
private static String url="jdbc:mysql://localhost:3306/test";
private static String username="root";
private static String password="";
private HungrySinge() {}
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public synchronized static HungrySinge getSingle(){
if(single==null){
single=new HungrySinge();
}
return single;
}
public synchronized static Connection getConnection() throws SQLException{
if(connection == null){
connection = DriverManager.getConnection(url, username, password);
}
return connection ;
}
}
测试类:
package com;
import java.sql.Connection;
import java.sql.SQLException;
public class HungrySingleTest {
public static void main(String[] args) throws SQLException {
HungrySinge single1= HungrySinge.getSingle();
HungrySinge single2= HungrySinge.getSingle();
System.out.println(single1==single2);
Connection connection1 = HungrySinge.getConnection();
Connection connection2 = HungrySinge.getConnection();
System.out.println(connection1);
System.out.println(connection2);
System.out.println(connection1==connection2);
}
}
结果:
true
com.mysql.jdbc.JDBC4Connection@36fcd774
com.mysql.jdbc.JDBC4Connection@36fcd774
true
可以对上面的类改进:
public static HungrySinge getSingle(){
if(single==null){
synchronized(HungrySinge.class){
single=new HungrySinge();
}
}
return single;
}
public static Connection getConnection() throws SQLException{
if(connection == null){
synchronized(HungrySinge.class){
connection = DriverManager.getConnection(url, username, password);
}
}
return connection ;
}
这两个方法改进:不要方法上再加上synchronied可能会造成死锁的现象.
单例模式的应用:
在一个系统中要求只有一个类的实例时应当使用单例模式.java语言中的Runtime对象就是一个单例模式