什么是单例模式?
单例模式即一个类在程序中永远只有一个实例。
单例的写法。
- 饿汉式(静态常量)
- 饿汉式(静态代码块)
- 懒汉式(线程不安全)
- 懒汉式(线程安全,同步方法)
- 懒汉式(线程安全,同步代码块)
- 双重检查
- 静态内部类
- 枚举
上代码。
- 饿汉式(静态常量)
//优点:写法简单,类加载时实例化,避免线程同步问题。
//缺点:类加载时实例化,无法达到懒加载的效果。浪费内存。
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量
private static final SingleObj instance = new SingleObj();
//返回实例
public static SingleObj getInstance(){
return instance;
}
}
- 饿汉式(静态代码块)
//优缺点和上面一样,只是写法不同
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量
private static SingleObj instance;
//静态代码块执行时创建实例。
static {
instance = new SingleObj();
}
//返回实例
public static SingleObj getInstance(){
return instance;
}
}
- 懒汉式(线程不安全)
//优点:懒加载,使用时才会new
//缺点:线程不安全,当多线程同时到if时,会创建多个实例。
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量
private static SingleObj instance;
//返回实例
public static SingleObj getInstance(){
//如果instance为空 则new一个
if (instance==null){
instance = new SingleObj();
}
return instance;
}
}
- 懒汉式(线程安全,同步方法)
//优点:解决了线程不安全问题。
//缺点:每次调用getInstance()都要同步,效率低。
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量
private static SingleObj instance;
//返回实例 方法同步synchronized
public static synchronized SingleObj getInstance(){
if (instance==null){
instance = new SingleObj();
}
return instance;
}
}
- 懒汉式(线程安全,同步代码块)
//这种方法是为了解决上面每次调用的同步问题,把synchronized加在了代码块中。
//而在多线程同时运行到if中时,仍然会产生多个实例。不推荐使用
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量
private static SingleObj instance;
//返回实例 代码块同步
public static SingleObj getInstance(){
if (instance==null){
synchronized (SingleObj.class){
instance = new SingleObj();
}
}
return instance;
}
}
- 双重检查
//优点:线程安全,懒加载。
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
//提供静态变量 volatile - 保证变量的内存可见性 - 禁止指令重排序
private volatile static SingleObj instance;
//返回实例
public static SingleObj getInstance(){
//进行两次判断
if (instance==null){
synchronized (SingleObj.class){
if (instance==null){
instance = new SingleObj();
}
}
}
return instance;
}
}
- 静态内部类
//优点:懒加载(调用getInstance()时,才会加载内部类实例化),线程安全
public class SingleObj {
//私有化构造方法,防止外部new
private SingleObj(){
}
private static class SingleInstance{
private static final SingleObj instance = new SingleObj();
}
//返回实例
public static SingleObj getInstance(){
return SingleInstance.instance;
}
}
- 枚举
public enum SingleObj {
instance;
public void hello(){
}
}
网友评论