码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式(一):单例模式

时间:2020-07-15 01:18:17      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:pack   模式   code   sys   click   赋值   初始化   style   width   

一.单例模式的特点:

    在单例模式的开始和结束中,这个过程只会实例化一个对象。

 

二.懒汉式的写法及特点:

    懒汉式顾名思义就是越懒越好,你不用我,我便不去实例化。只有在调用时,才会进行实例化操作。

技术图片
 1 package com.cllover.lazy;
 2 
 3 public class LazySingleton {
 4     public static void main(String[] args) {
 5 
 6             lazyinstance instance = lazyinstance.getInstance();
 7             System.out.println(instance+"\n");
 8             lazyinstance instance1 = lazyinstance.getInstance();
 9             System.out.println(instance1+"\n");
10 
11 
12     }
13 }
14 
15 
16 class lazyinstance{
17 
18     private static lazyinstance instance;
19 
20     private lazyinstance(){
21     }
22 
23     public  static lazyinstance getInstance() {
24         if (instance == null){
25           instance = new lazyinstance();
26         }
27         return instance;
28     }
29 }
单线程下的懒汉式

    在单线程下,由于第一次进行实例化在此前并没有提前进行实例化操作,所以符合条件进行实例化操作 

技术图片

    在实例化化得过程中进行了new空间 ,初始化和引用赋值等几个步骤。再进行第二次实例化时,由于第一次已经存在值,所以第二次条件不成立,直接返回第一次实例化结果,所以两次结果相等为true

技术图片

 技术图片

 

三.那么在多线程下是否安全那?

技术图片
 1 package com.cllover.lazy;
 2 
 3 public class LazySingleton {
 4 
 5     public static void main(String[] args) {
 6         //线程一
 7         new Thread(()->{
 8             lazyinstance instance  = lazyinstance.getInstance();
 9             System.out.println(instance+"\n");
10         }).start();
11         //线程二
12         new Thread(()->{
13             lazyinstance instance1  = lazyinstance.getInstance();
14             System.out.println(instance1+"\n");
15         }).start();
16     }
17 }
18 class lazyinstance{
19 
20     private static lazyinstance instance;
21 
22     private lazyinstance(){
23     }
24 
25     public  static lazyinstance getInstance() {
26 
27         if (instance == null){
28           instance = new lazyinstance();
29         }
30         return instance;
31     }
32 }

多线程下的懒汉式

技术图片

    很显然在多线程下,各自线程进行自己的实例化操作, 造成不安全的因素在里面,在进行相同的实例化操作下 并不相同,

    与此同时,对实例化进行加lock或者加 synchronized 进行加锁。

 

四.使用synchronized 同步锁

    synchronized能够解决在多线程的条件下,控制线程无法同时进行,进行同步堵塞。在这里定义了三个线程进行验证  

技术图片
 1 package com.cllover.lazy;
 2 
 3 public class LazySingleton {
 4 
 5     public static void main(String[] args) {
 6         //线程一
 7         new Thread(()->{
 8             lazyinstance instance  = lazyinstance.getInstance();
 9             System.out.println(instance+"\n");
10         }).start();
11         //线程二
12         new Thread(()->{
13             lazyinstance instance1  = lazyinstance.getInstance();
14             System.out.println(instance1+"\n");
15         }).start();
16         //线程三
17         new Thread(()->{
18             lazyinstance instance2  = lazyinstance.getInstance();
19             System.out.println(instance2+"\n");
20         }).start();
21     }
22 }
23 class lazyinstance{
24 
25     private static lazyinstance instance;
26 
27     private lazyinstance(){
28     }
29 
30     public  static lazyinstance getInstance() {
31 
32         if (instance == null){
33             //同步堵塞
34             synchronized (lazyinstance.class){
35                 //是否进行过实例化
36                 if (instance == null){
37                     instance = new lazyinstance();
38                 }
39             }
40         }
41         return instance;
42     }
43 }
synchronized的加入

 

技术图片

   在进行了加锁之后,结果相同。

原因:

技术图片

     在三个线程同时运行中,由于synchronized的作用并没有同时进行实例化操作。

    先有“线程一”就行实例化,由于是第一次实例化所以条件符合,new了一个新的实例。第一个线程结束后,第二个线程由“线程三”开始进行检测是否已经存在instance的值。由于“线程一”的实例化,进行了引用赋值,所以在“线程二”中可以直接获取值。并在检测中显示不符合条件,存在这个值。并带回这个结果。

技术图片

     最后进行“线程一”由于存在值,所以不用new新的实例,并带回结果。所以再加入锁的情况下懒汉式多线程相对较为安全。

技术图片

 

 

五.饿汉式:

 

设计模式(一):单例模式

标签:pack   模式   code   sys   click   赋值   初始化   style   width   

原文地址:https://www.cnblogs.com/CllOVER/p/13303009.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!