尚硅谷面试第一季-02单例设计模式
课堂重点笔记:
课堂代码实现:
饿汉式:
1 package 单例设计模式; 2 3 /** 4 * @author zsh 5 * @company wlgzs 6 * @create 2019-03-26 8:37 7 * @Describe 直接实例化饿汉式(简介直观) 8 * 直接创建实例对象的饿汉式,不管你是否需要这个对象都会创建 9 * 10 * (1)构造器私有化 11 * (2)自行创建,并且静态变量保存 12 * (3)向外提供实例 13 * (4)强调这是一个单例,我们可以用final关键字修饰 14 */ 15 public class Singleton1 { 16 public static final Singleton1 INSTANCE = new Singleton1(); 17 private Singleton1(){ 18 19 } 20 } 21 22 package 单例设计模式; 23 24 /** 25 * @author zsh 26 * @company wlgzs 27 * @create 2019-03-26 8:46 28 * @Describe Singleton1测试类 29 */ 30 public class TestSingleton1 { 31 public static void main(String[] args) { 32 Singleton1 s = Singleton1.INSTANCE; 33 System.out.println(s); 34 } 35 }
1 package 单例设计模式; 2 3 /** 4 * @author zsh 5 * @company wlgzs 6 * @create 2019-03-26 8:44 7 * @Describe 枚举式(最简洁) 8 * 枚举类型:表示该类型的对象是有限个 9 * 我们可以设定为1个,即成为了单例 10 * 枚举默认即为private 11 */ 12 public enum Singleton2 { 13 INSTANCE 14 } 15 16 package 单例设计模式; 17 18 /** 19 * @author zsh 20 * @company wlgzs 21 * @create 2019-03-26 8:48 22 * @Describe Singleton2测试类 23 */ 24 public class TestSingleton2 { 25 public static void main(String[] args) { 26 Singleton2 s = Singleton2.INSTANCE; 27 System.out.println(s); 28 } 29 }
1 package 单例设计模式; 2 3 import java.io.*; 4 import java.util.Properties; 5 6 /** 7 * @author zsh 8 * @company wlgzs 9 * @create 2019-03-26 8:50 10 * @Describe 静态代码块饿汉式(适合复杂实例化) 11 * 12 */ 13 public class Singleton3 { 14 public static final Singleton3 INSTANCE; 15 private String info; 16 17 //饿汉式,直接创建对象,不存在线程安全问题 18 static { 19 Properties properties = new Properties(); 20 try { 21 String path = System.getProperty("user.dir")+"/src/main/resources/singleton.properties"; 22 properties.load(new InputStreamReader(new FileInputStream(path))); 23 INSTANCE = new Singleton3(properties.getProperty("info")); 24 } catch (IOException e) { 25 throw new RuntimeException(e); 26 } 27 } 28 29 public String getInfo() { 30 return info; 31 } 32 33 public void setInfo(String info) { 34 this.info = info; 35 } 36 37 @Override 38 public String toString() { 39 return "Singleton3{" + 40 "info='" + info + '\'' + 41 '}'; 42 } 43 44 private Singleton3(String info){ 45 this.info = info; 46 } 47 } 48 49 50 package 单例设计模式; 51 52 /** 53 * @author zsh 54 * @company wlgzs 55 * @create 2019-03-26 9:02 56 * @Describe Singleton3测试类 57 */ 58 public class TestSingleton3 { 59 public static void main(String[] args) { 60 Singleton3 s = Singleton3.INSTANCE; 61 System.out.println(s); 62 } 63 }
懒汉式:
1 package 单例设计模式; 2 3 /** 4 * @author zsh 5 * @company wlgzs 6 * @create 2019-03-26 9:20 7 * @Describe 懒汉式1 8 * 线程不安全(适合于单线程) 9 * 延迟创建实例对象,存在线程安全问题 10 * 11 * (1)构造器私有化 12 * (2)用一个静态变量保存这个唯一的实例 13 * (3)提供一个静态方法,获取这个实例对象 14 */ 15 public class Singleton4 { 16 private static Singleton4 instance; 17 private Singleton4(){ 18 19 } 20 21 public static Singleton4 getInstance(){ 22 if (instance == null){ 23 try { 24 Thread.sleep(100); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 instance = new Singleton4(); 29 } 30 return instance; 31 } 32 } 33 34 package 单例设计模式; 35 36 import java.util.Collection; 37 import java.util.List; 38 import java.util.concurrent.*; 39 40 /** 41 * @author zsh 42 * @company wlgzs 43 * @create 2019-03-26 9:25 44 * @Describe Singleton4测试类 45 */ 46 public class TestSingleton4 { 47 public static void main(String[] args) throws ExecutionException, InterruptedException { 48 /*//单线程情况下 49 Singleton4 s1 = Singleton4.getInstance(); 50 Singleton4 s2 = Singleton4.getInstance(); 51 System.out.println(s1 == s2); 52 System.out.println(s1); 53 System.out.println(s2);*/ 54 55 //多线程情况下 56 Callable<Singleton4> c = new Callable<Singleton4>() { 57 @Override 58 public Singleton4 call() throws Exception { 59 return Singleton4.getInstance(); 60 } 61 }; 62 //创建线程池 63 ExecutorService es = Executors.newFixedThreadPool(2); 64 Future<Singleton4> f1 = es.submit(c); 65 Future<Singleton4> f2 = es.submit(c); 66 67 Singleton4 s3 = f1.get(); 68 Singleton4 s4 =f2.get(); 69 70 System.out.println(s3 == s4); 71 System.out.println(s3); 72 System.out.println(s4); 73 74 es.shutdown(); 75 76 } 77 }
1 package 单例设计模式; 2 3 /** 4 * @author zsh 5 * @company wlgzs 6 * @create 2019-03-26 9:43 7 * @Describe 懒汉式2 8 * 线程安全(适合于多线程) 9 */ 10 public class Singleton5 { 11 private static Singleton5 instance; 12 private Singleton5(){ 13 14 } 15 16 public static Singleton5 getInstance(){ 17 if (instance == null) { 18 synchronized (Singleton5.class) { 19 if (instance == null) { 20 try { 21 Thread.sleep(1000); 22 } catch (InterruptedException e) { 23 e.printStackTrace(); 24 } 25 instance = new Singleton5(); 26 } 27 } 28 } 29 return instance; 30 } 31 } 32 33 package 单例设计模式; 34 35 import java.util.concurrent.*; 36 37 /** 38 * @author zsh 39 * @company wlgzs 40 * @create 2019-03-26 9:25 41 * @Describe Singleton5测试类 42 */ 43 public class TestSingleton5 { 44 public static void main(String[] args) throws ExecutionException, InterruptedException { 45 //多线程情况下 46 Callable<Singleton5> c = new Callable<Singleton5>() { 47 @Override 48 public Singleton5 call() throws Exception { 49 return Singleton5.getInstance(); 50 } 51 }; 52 //创建线程池 53 ExecutorService es = Executors.newFixedThreadPool(2); 54 Future<Singleton5> f1 = es.submit(c); 55 Future<Singleton5> f2 = es.submit(c); 56 57 Singleton5 s3 = f1.get(); 58 Singleton5 s4 =f2.get(); 59 60 System.out.println(s3 == s4); 61 System.out.println(s3); 62 System.out.println(s4); 63 64 es.shutdown(); 65 66 } 67 }
1 package 单例设计模式; 2 3 /** 4 * @author zsh 5 * @company wlgzs 6 * @create 2019-03-26 10:42 7 * @Describe 懒汉式3 8 * 静态内部类形式(适合多线程) 9 * 在内部类被加载和初始化时,才创建INSTANCE对象 10 * 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的。 11 * 因为实在内部类加载和初始化时,创建的,因此线程是安全的 12 */ 13 public class Singleton6 { 14 15 private Singleton6(){ 16 17 } 18 19 private static class Inner{ 20 private static final Singleton6 INSTANCE = new Singleton6(); 21 } 22 23 public static Singleton6 getInstance(){ 24 return Inner.INSTANCE; 25 } 26 } 27 28 package 单例设计模式; 29 30 import java.util.concurrent.*; 31 32 /** 33 * @author zsh 34 * @company wlgzs 35 * @create 2019-03-26 9:25 36 * @Describe Singleton6测试类 37 */ 38 public class TestSingleton6 { 39 public static void main(String[] args) throws ExecutionException, InterruptedException { 40 /*//单线程情况下 41 Singleton6 s1 = Singleton6.getInstance(); 42 Singleton6 s2 = Singleton6.getInstance(); 43 System.out.println(s1 == s2); 44 System.out.println(s1); 45 System.out.println(s2);*/ 46 47 //多线程情况下 48 Callable<Singleton6> c = new Callable<Singleton6>() { 49 @Override 50 public Singleton6 call() throws Exception { 51 return Singleton6.getInstance(); 52 } 53 }; 54 //创建线程池 55 ExecutorService es = Executors.newFixedThreadPool(2); 56 Future<Singleton6> f1 = es.submit(c); 57 Future<Singleton6> f2 = es.submit(c); 58 59 Singleton6 s3 = f1.get(); 60 Singleton6 s4 =f2.get(); 61 62 System.out.println(s3 == s4); 63 System.out.println(s3); 64 System.out.println(s4); 65 66 es.shutdown(); 67 68 } 69 }
小结: