Java中单例模式案例
整理Java开发中对这方面的使用,文章持续更新。
本文章仅供产考,如有不符,欢迎留言评论。
设计思路:
只能创建唯一实例(无参构造方法是private修饰,不能直接new对象)
单例模式大致分为:饿汉模式(线程不安全)和懒汉模式(线程安全)
其中还包括:懒汉式同步锁、双重锁、静态内部类、枚举(特殊的单例模式)
1、饿汉模式
package SingleModel;
public class SingleModel{
private final static SingleModel singleModel= new SingleModel();
private SingleModel() {}
public static SingleModel getInstance() {
return singleModel;
}
}
2、懒汉模式
package SingleModel;
public class SingleModel {
private static SingleModel instance=null;
private SingleModel(){}
public static SingleModel getInstance(){
// 首次生成单例对象时,如果多个线程同时调用getInstance方法,这个条件针对多个线程同时成立,那么就会生成多个单例对象
if(instance==null){
instance=new SingleModel();
}
return instance;
}
}
3、懒汉式同步锁
package SingleModel;
public class SingleModel {
private static SingleModel instance=null;
private SingleModel(){}
public static SingleModel getInstance(){
// 加上线程同步锁,确保每次只有一个线程进入
synchronized (SingleModel.class){
if (instance==null){
instance=new SingleModel();
}
}
return instance;
}
}
4、双重锁
package SingleModel;
public class SingleModel {
// 加上volatile关键字,线程每次使用到被volatile关键字修饰的变量时,都会去堆里拿最新的数据
private static volatile SingleModel instance=null;
private SingleModel(){}
public static SingleModel getInstance(){
// 在懒汉式同步锁的基础上加上了一个判断,如果单例对象不为空,就不需要执行获得对象同步锁的代码,从而提高效率
if(instance==null){
synchronized (SingleModel.class){
if (instance==null){
instance=new SingleModel();
}
}
}
return instance;
}
}
5、静态内部类
package SingleModel;
/**
*实现简单,懒加载,线程安全
*但是增加了一个静态内部类,加载文件增大
*/
public class SingleModel{
/**
* 私有静态内部类,程序只有当使用到静态内部类是才会去加载静态内部类,然后生成单例对象
*/
private static class SingleModelToStatic{
public static SingleModel singleModel= new SingleModel();
}
private SingleModel() {}
/**
* 只用调用了getInstance方法,程序中使用到了静态内部类SingleModelToStatic,才会去加载SingleModelToStatic,生成单例对象
*/
public static SingleModel getInstance() {
return SingleModelToStatic.singleModel;
}
}
6、枚举
/**
* 优点:线程安全,不用担心序列化和反射问题
* 缺点:枚举占用的内存会多一点
*/
public enum SingleModel{
SUCCESS(200,"操作成功"),
FAIL(500,"操作失败");
private int code;
private String name;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//定义枚举参数
SingleModel(int code,String name){
this.code=code;
this.name=name;
}
}