单例模式,最常见的就是饥饿模式和懒汉模式,饥饿模式直接实例化对象,懒汉模式在调用方法时进行实例化对象(如果有了就不创建了)。在多线程模式中,考虑到性能和线程安全问题,我们一般选择下面两种比较经典的单例模式,在性能提高的同时,又保证了线程安全。
dubble check instance 两层的if,双层判断
1 package com.java.day02_Single; 2 3 public class DubbleSingleton { 4 private static DubbleSingleton ds; 5 6 public static DubbleSingleton getDs(){ 7 if(ds==null){ 8 try { 9 //模拟初始化对象准备时间 10 Thread.sleep(3000); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 15 synchronized (DubbleSingleton.class) { 16 if(ds==null){//第二次判断:可能在得到锁之前,上一个释放锁的线程已经创建好了对象,所以需要再进行一次判断 17 ds=new DubbleSingleton(); 18 } 19 } 20 21 22 } 23 24 return ds; 25 } 26 27 public static void main(String[] args) { 28 Thread t1 = new Thread(new Runnable() { 29 public void run() { 30 System.out.println("线程"+Thread.currentThread().getName()+":"+DubbleSingleton.getDs().hashCode()); 31 } 32 },"t1"); 33 34 Thread t2 = new Thread(new Runnable() { 35 public void run() { 36 System.out.println("线程"+Thread.currentThread().getName()+":"+DubbleSingleton.getDs().hashCode()); 37 } 38 },"t2"); 39 40 t1.start(); 41 t2.start(); 42 43 44 } 45 46 47 48 49 50 }
运行结果:
1 线程t2:174227757 2 线程t1:174227757
static inner class 静态内部类(常用,简单,安全,支持多线程)
1 package com.java.day02_Single; 2 3 /** 4 * 静态内部类 5 * @author syousetu 6 * 7 */ 8 public class InnerSingleton { 9 private static class Singletion{ 10 private static Singletion single=new Singletion(); 11 } 12 13 public static Singletion getInstance(){ 14 return Singletion.single; 15 } 16 17 }