单例模式
单例模式
饿汉式
由于对象在类里面才能被创建,而且是静态的,所以,被创建的对象始终都是一个,由于在类装载时就被完成了实例化,所以没有线程安全问题,如果没有使用这个实例,会造成内存浪费
//饿汉式
class Singleton1{
public String name;
private static final Singleton1 instance = new Singleton1();
private Singleton1(){
System.out.println("Singleton1,被构建对象");
}
public static Singleton1 getInstance(){
return instance;
}
}
懒汉式
线程不安全
起到了懒加载效果,但是只能在单线程使用,多线程会不安全,因为当多个线程并发同时判断instance为空时,就会相应的实例化多个对象。
class Singleton { //线程不安全
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() { //调用时才实例化对象,懒汉式
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
以线程安全的方式创建
上面线程不安全,那上锁不就好了,使用synchronized关键字。 这样虽然解决了线程安全,但其实实例化操作只做一次,而获取实例(即getInstance)的操作是很多次的,把调用的方法加上同步,会大大降低效率。
class Singleton { //线程安全
private static Singleton instance;
private Singleton() {}
//synchronized同步处理
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
class Singleton { //双重检查
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) { //判断是否实例化
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance; //否则直接return
}
}
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
//静态内部类,包含一个静态属性:Singleton
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
//对外公有的静态方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
使用枚举也可以完成单例模式
enum Singleton {
INSTANCE; //属性
public void say() {
System.out.println("记得三连~");
}
}
public static void main(String[] args) {
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1 == instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
instance1.say();
}
测试结果
- true
- 460141958
- 460141958
- happy!
.

浙公网安备 33010602011771号