版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
一、概览
二、单例模式
(1)、饿汉式(静态常量)——推荐使用
package Singleton;
public class Singleton1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
//饿汉式
class Singleton {
//私有构造器,防止别人去new。
private Singleton() {}
private final static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
运行结果:
true
366712642
366712642
因为静态属性在类加载的时候就被赋了值,因此在后续每次调用中都是同一个对象。
(2)、饿汉式(静态代码块)——推荐使用
将实例化放到静态代码块中即可。
(3)、双重检查——推荐使用
package Singleton;
public class Singleton1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
class Singleton {
//私有构造器,外部不能new。
private Singleton() {}
// 线程将值一改变后就刷到主存去,即这个值改变后对其他线程来说是可见的。
private static volatile Singleton instance;
public static Singleton getInstance() {
if(instance == null) {// c\d\e\线程来访问时就被过滤掉,从而不执行线程同步节约资源
synchronized (Singleton.class) {
if(instance == null) {// a线程实例化后将b线程过滤掉
instance = new Singleton();
}
}
}
return instance;
}
}
(4)、静态内部类——推荐使用
package Singleton;
public class Singleton1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
class Singleton {
//私有构造器,外部不能new。
private Singleton() {}
//外部类加载的时候不会加载内部内
private static class SingletonInstance{
private static final Singleton instance = new Singleton();
}
//再调用内部内属性的时候加载一次内部内
public static Singleton getInstance() {
return SingletonInstance.instance;
}
}
(5)、懒汉式(线程不安全)——不推荐使用
package Singleton;
public class Singleton1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
//懒汉式
class Singleton {
//私有构造器,外部不能new。
private Singleton() {}
private static Singleton instance;
// 使用到的时候才去创建实例,即懒汉式,线程不安全
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
(6)、懒汉式(线程安全)——不推荐使用
加上synchronized即可。
(7)、枚举方式
枚举类里面的每一个元素表示这个枚举类的不同的实例。
package Singleton;
public class Singleton1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
enum Singleton {
INSTANCE;
public void method() {
System.out.println("方法!");
}
}