单例模式与线程安全
一。饿汉模式(立即加载)
立即加载就是使用类的时候已经将对象创建完毕。调用方法前,实例已经被创建了。
public class MyObject{
//立即加载方式 == 饿汉模式
private static MyObject myObject = new MyObject();
private MyObject(){};
public static MyObject getInstance(){
//此代码版本为立即加载,缺点是不能有其他实例变量
//线程安全的
return myObject;
}
}
二。懒汉模式(延迟加载,线程不安全)
延迟加载是指在调用方法时实例才被创建。
public class MyObject{
private static MyObject myObject;
private MyObject(){};
public static MyObject getInstance(){
//延迟加载
if(myObject ! = null){
}else{
myObject = new MyObject();
}
return myObject;
}
}
这种实现方式在多线程的情况下可能会创建出多个实例。并不是线程安全的。
三。懒汉模式(线程安全解决方案)
①声明Synchronized关键字
既然多个线程可以同时进入getInstance()方法,那么只需要对getInstance()方法声明Synchronized关键字即可。
public class MyObject{
private static MyObject myObject;
private MyObject(){};
//这样设置同步方法效率太低了
//整个方法被上锁了
synchronized public static MyObject getInstance(){
if(myObject ! = null){
}else{
myObject = new MyObject();
}
return myObject;
}
}
②使用DCL双检查锁机制
public class MyObject{
private volatile static MyObject myObject;
private MyObject(){};
public static MyObject getInstance(){
try{
if(myObject != null){
}else{
synchronized(MyObject.class){
if(myObject == null){
myObject = new MyObject();
}
}
}
}catch(Exception e){
e.printStackTrace();
}
return myObject;
}
}
四。静态内部类
即实现了延迟加载,又保证了线程安全。
public class MyObject{
//内部类方式
private static class MyObjectHandler {
private static MyObject myObject = new MyObject();
}
private MyObject(){};
public static MyObject getInstance(){
return MyObjectHandler.myObject;
}
}
五。使用static代码块来实现单例模式
静态代码块中的代码在使用类的时候就已经执行了,所以可以应用静态代码块的这个特性来实现单例设计模式。
public class MyObject{
private static MyObject instance = null;
private MyObject(){};
static{ instance = new MyObject();};
public static MyObject getInstance(){
return instance;
}
}
六。使用枚举数据类型实现单例模式
public enum EnumObject {
connectionFactory;
private Connection connection;
private EnumObject(){
try{
connection = (Connection) DriverManager.getConnection("");
}catch(Exception e){
e.printStackTrace();
}
}
public Connection getConnection(){
return connection;
}
}