单列模式是什么?
单列模式是创建型模式的一种,同样一个对象(实例)在内存中只会有一份,只并只有一个全局的访问点。单列分为好多种实现,其中有线程安全和线程不安全,大类有懒汉和饿汉;
单列模式可以干嘛?
可以解决一个对象重复的创建和销毁,减少内存的开销,保存只在内存只有一份。就比如:一个学校一般只有一个正校长;
代码地址:https://gitee.com/hong99/design-model/issues/I1IMES
代码实现
懒汉:都是被别人推着才去做的,这样线程不安全(也有安全)
饿汉: 先创建对象,每次直接返回实例化后单例结果。
比如:
我去吃饭一到饭管菜都已经上好了,就直接开吃了,这个是饿汉;
我去吃饭一到那里是等了半天,一边上菜一边催,才好不容易把菜上全了,这样的叫懒汉,要别人催才给;
public class HungrySingle {
//创建 HungrySingle 的一个对象 、
private static HungrySingle instance = new HungrySingle();
//让构造函数为 private,这样该类就不会被实例化
private HungrySingle() {
} //获取唯一可用的对象
public static HungrySingle getInstance() {
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton(){}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
public class LazySingleSafery {
private static LazySingleSafery lazySingleSafery;
private LazySingleSafery(){
}
public static synchronized LazySingleSafery getInstance(){
if(lazySingleSafery == null){
lazySingleSafery = new LazySingleSafery();
}
return lazySingleSafery;
}
}
public class DoubleCheckLazySingleSafery {
private static DoubleCheckLazySingleSafery instance;
private DoubleCheckLazySingleSafery(){
}
public static DoubleCheckLazySingleSafery getInstance(){
if(instance == null){
synchronized (DoubleCheckLazySingleSafery.class){
if(instance == null){
instance = new DoubleCheckLazySingleSafery();
}
}
}
return instance;
}
}
public class StaticInnerSingle {
private static class SingleHolder{
private static final StaticInnerSingle INSTANCE = new StaticInnerSingle();
}
private StaticInnerSingle(){
}
public static final StaticInnerSingle getInstance(){
return SingleHolder.INSTANCE;
}
}
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 HungrySingle() 是不可见的
//HungrySingle object = new HungrySingle();
//获取唯一可用的对象 饿汉
ExecutorService lazyThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
lazyThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("饿汉(安全)"+ HungrySingle.getInstance());
}
});
}
//懒汉 线程不安全
ExecutorService hungryThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
hungryThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉(不安全)"+LazySingleton.getInstance());
}
});
}
//懒汉 线程安全 性能低
ExecutorService hungrySaferyThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
hungrySaferyThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉(安全)"+LazySingleSafery.getInstance());
}
});
}
//懒汉 线程安全 性能高
ExecutorService DoubleCheckThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
DoubleCheckThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("懒汉双重检查(安全)"+DoubleCheckLazySingleSafery.getInstance());
}
});
}
//懒汉 线程安全 性能高
ExecutorService staticInnerSingleThreadPool = Executors.newFixedThreadPool(10);
for (int i =0;i<10;i++){
staticInnerSingleThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("登记式/静态内部类(安全)"+StaticInnerSingle.getInstance());
}
});
}
}
}
结果
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.3\lib\idea_rt.jar=58612:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;D:\ideaWorkSpace\design-model\target\classes" com.hong.base.singlemodel.SingletonPatternDemo
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
饿汉(安全)com.hong.base.singlemodel.HungrySingle@2d164da7
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@710f2fc4
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@1bd08742
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(不安全)com.hong.base.singlemodel.LazySingleton@7c716752
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉(安全)com.hong.base.singlemodel.LazySingleSafery@a49a412
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
懒汉双重检查(安全)com.hong.base.singlemodel.DoubleCheckLazySingleSafery@63db9a8d
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
登记式/静态内部类(安全)com.hong.base.singlemodel.StaticInnerSingle@6d037c
最后我想说,判断一个对象是不是单列只需要看对象里面有没有private 类名 (){} 如果有肯定是单例。
代码地址:https://gitee.com/hong99/design-model/issues/I1IMES
参考资料:
《大话设计模式》
《研磨设计模式》
《设计模式之禅》
《Java与模式》