单例模式的几个特征:
1、构造私有
2、对象私有、静态。
3、存在一个调用对象的公共静态方法。
懒汉模式
package com.singleton;
public class SingletonLazy {
private static SingletonLazy singletonLazy;
private SingletonLazy() {
}
public static synchronized SingletonLazy singletonLazyInstance(){
if(singletonLazy==null){
singletonLazy = new SingletonLazy();
}
return singletonLazy;
}
}
饿汉模式
package com.singleton;
public class SingletonHungry {
private final static SingletonHungry singletonHungry = new SingletonHungry();
private SingletonHungry(){
}
public static SingletonHungry getSingletonHungry(){
return singletonHungry;
}
}
静态内部类加载模式
package com.singleton;
public class SingletonClass {
private static class SingletonClassStatic{
private static final SingletonClass SINGLETON_CLASS_STATIC= new SingletonClass();
}
private SingletonClass(){}
public static SingletonClass getSingleton(){
return SingletonClassStatic.SINGLETON_CLASS_STATIC;
}
}
调度快慢:饿汉式>内部类加载>懒加载
空间效率:懒加载>内部类加载>饿汉式
注意:没有加锁的懒汉式是线程不安全的。
测试
package com.singleton;
public class Client {
public static void main(String[] args) {
/*
*
* SingletonLazy singletonLazy1 = SingletonLazy.singletonLazyInstance();
SingletonLazy singletonLazy2 = SingletonLazy.singletonLazyInstance();
System.out.println(singletonLazy1 == singletonLazy2);
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000000; j++) {
Object singletonLazy = SingletonLazy.singletonLazyInstance();
}
}
}).start();
}
long end = System.currentTimeMillis();
System.out.println(end-start);
* */
/*
*
*
* SingletonHungry singletonHungry = SingletonHungry.getSingletonHungry();
SingletonHungry singletonHungry2 = SingletonHungry.getSingletonHungry();
System.out.println(singletonHungry==singletonHungry2);
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000000; j++) {
Object o = singletonHungry.getSingletonHungry();
}
}
}).start();
}
long end = System.currentTimeMillis();
System.out.println(end-start);
* */
SingletonClass singletonClass = SingletonClass.getSingleton();
SingletonClass singletonClass2 = SingletonClass.getSingleton();
System.out.println(singletonClass2==singletonClass);
}
}