单例模式简单了解

 1 package com.iotek.threadtest;
 2 
 3 public class SingleTonDemo {
 4 
 5     /** 单例模式:
 6      * 单例模式有饿汉模式和懒汉模式,懒汉式即延迟初始化单例.
 7      * 在多线程环境下,简单的懒汉式会有线程安全的困扰
 8      * 下面通过设计程序来实现线程安全的懒汉式单例模式:
 9      * 1.实现懒汉式单例模式
10      * 2.使用双重检查加锁机制解决线程安全问题
11      * 3.单例模式还有更好的解决方案,即使用静态类方式
12      * @param args
13      * @version14      */
15     public static void main(String[] args) {
16         SingleTon.getInstance();
17         SingleTon.getInstance();
18         // 上面调用2次getInstance()方法,但构造方法里的语句只打印了一次,说明只产生了一个对象
19         SThread sThread = new SThread(); // 创建一个Runnable接口的实现类对象
20         Thread t1 = new Thread(sThread);
21         t1.start();
22         /*
23          * 线程的创建方式2: 创建一个Thread类对象,将Runnable接口的实现类(对象)作为 实际参数传入Thread类的构造方法 3.重写
24          * Runnable 接口中的run()方法
25          */
26         Thread t2 = new Thread(sThread);
27         t2.start();
28     }
29 
30 }
31 
32 class SThread implements Runnable {
33 
34     @Override
35     public void run() {
36         SingleTon.getInstance();
37     }
38 
39 }
40 
41 class SingleTon {
42     private static SingleTon singleTon = null;
43 //    单例模式中,要返回的这个singleTon对象必须是static的,
44 
45     private SingleTon() {
46         System.out.println("单例模式");
47     }
48 
49     public static SingleTon getInstance() {
50 //  static:要想外部程序访问,只能设为静态的,静态方法只能访问静态变量,所以属性也要设置为静态的
51         if(singleTon ==null) {
52             //只有singleTon变量为null时,才执行同步块,否则直接返回singleTon变量
53             synchronized (SingleTon.class) {
54                 if (singleTon == null) {
55                     singleTon = new SingleTon();
56                 }
57             }
58         }
59         return singleTon;
60     }
61 }
62 
63 /*
64  * if (singleTon == null) { singleTon = new SingleTon(); }
65  * 分析这段代码,当第一个线程程序执行了singleTon == null,还未执行 singleTon = new SingleTon();
66  * 语句时,第二个线程此时如果也执行到了singleTon == null判断语句,那么将会再次调用 singleTon = new SingleTon();
67  * 语句,这样的话会2次产生对象,这样就会造成线程非安全操作,该如何避免这种情况? 只需将这段代码放到同步块synchronized (singleTon)
68  * {} 中 ,那么此处对象锁该使用哪个锁呢? 要想多个线程都使用这个对象的锁,那么需要使用一个共同的锁,可以用SingleTon.class这个对象的锁
69  */
70 
71 /* 当第一个线程进入同步块后,获得了SingleTon.class这个对象的锁,
72  * 第二个线程只能等待,只有当第一个线程执行完代码将锁释放后,第二个
73  * 线程获得该锁 才能启动第二个线程,第二个线程进来,判断 singleTon == null 
74  * 条件不满足,直接跳过new语句,执行return singleTon; 语句,但是这样会有
75  * 一个问题,第一个线程已经产生了一个对象之后,其他的线程就没必要再进来了,
76  * 也就是说没必须要再执行同步块,因此在外层再添加一个判断,只有当singleTon
77  * 这个引用变量为null时,才执行同步块,否则直接返回singleTon引用变量!!!
78  *      */            

 

单例模式要点:

静态属性:private static SingleTon singleTon = null;

构造方法私有化:private SingleTon(){}

对外提供静态的获取实例的方法:public static SingleTon getInstance() {}

 

posted @ 2018-01-04 12:14  清风拂来  阅读(216)  评论(0编辑  收藏  举报