单例模式简单了解
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() {}