• 并发编程中的设计模式-单例模式


    1.饿汉模式:在类加载的时候就创建对象,对系统的开销较大,但是不存在线程的安全问题;

     1 class Singleton1 {
     2     private static Singleton1 singleton = new Singleton1(); // 建立对象
     3     private Singleton1() {
     4         try {
     5             Thread.sleep(1000);
     6             System.out.println("构建这个对象可能耗时很长...");
     7         } catch (InterruptedException e) {
     8             e.printStackTrace();
     9         }
    10     }
    11     public static Singleton1 getInstance() {
    12         return singleton;// 直接返回单例对象
    13     }
    14     @Override
    15     public String toString() {
    16         return ""+this.hashCode();
    17     }
    18 }
    19 
    20 public class DemoThread22 {
    21     public static void main(String[] args) throws InterruptedException {
    22         
    23         ExecutorService es = Executors.newFixedThreadPool(10);
    24         
    25         for(int i=0;i<10;i++){
    26             es.execute(new Runnable() {
    27                 @Override
    28                 public void run() {
    29                     Singleton1 instance = Singleton1.getInstance();
    30                     System.out.println(instance);
    31                 }
    32             });
    33         }
    34         
    35         es.shutdown();
    36     }
    37 }

    2.懒汉模式一:懒汉模式在需要对象的时候才进行对象的创建,

    
    
     1 class Singleton2 {
     2     private static Singleton2 singleton = null; // 不建立对象
     3     private Singleton2() {
     4     }
     5     /*synchronized 可以解决线程安全问题,但是存在性能问题,即使singleton!=null也需要先获得锁*/
     6     public synchronized static Singleton2 getInstance() {
     7         if (singleton == null) { // 先判断是否为空
     8             try {
     9                 Thread.sleep(1000);
    10                 System.out.println("构建这个对象可能耗时很长...");
    11             } catch (InterruptedException e) {
    12                 e.printStackTrace();
    13             }
    14             singleton = new Singleton2(); // 懒汉式做法
    15         }
    16         return singleton;
    17     }
    18     
    19     @Override
    20     public String toString() {
    21         return ""+this.hashCode();
    22     }
    23 }
    24 public class DemoThread23 {
    25     public static void main(String[] args) throws InterruptedException {
    26 
    27         ExecutorService es = Executors.newFixedThreadPool(100);
    28 
    29         for (int i = 0; i < 100; i++) {
    30             es.execute(new Runnable() {
    31                 @Override
    32                 public void run() {
    33                     System.out.println(Singleton2.getInstance());
    34                 }
    35             });
    36         }
    37 
    38         es.shutdown();
    39     }
    40 }
    
    
    
     

    3.懒汉模式性能安全的性能优化:上述的懒汉模式虽然是线程安全的,但是线程每次在调用getInstance()方法的时候都会对这个方法进行上锁,其实这样是没有必要的,因为当对象被创建之后就不需要对该方法上锁了,所以进行了如下优化。只有在第一次创建对象时上锁。

     1 class Singleton3 {
     2     private static Singleton3 singleton = null; // 不建立对象
     3     private Singleton3() {
     4     }
     5     /*synchronized 代码块进行双重检查,可以提高性能*/
     6     public static Singleton3 getInstance() {
     7         if (singleton == null) { // 先判断是否为空
     8             synchronized (Singleton3.class) {
     9                 //此处必须进行双重判断,否则依然存在线程安全问题
    10                 if(singleton == null){
    11                     try {
    12                         Thread.sleep(1000);
    13                         System.out.println("构建这个对象可能耗时很长...");
    14                     } catch (InterruptedException e) {
    15                         e.printStackTrace();
    16                     }
    17                     singleton = new Singleton3(); // 懒汉式做法
    18                 }
    19             }
    20         }
    21         return singleton;
    22     }
    23     
    24     @Override
    25     public String toString() {
    26         return ""+this.hashCode();
    27     }
    28 }
    29 public class DemoThread24 {
    30     public static void main(String[] args) throws InterruptedException {
    31 
    32         ExecutorService es = Executors.newFixedThreadPool(100);
    33 
    34         for (int i = 0; i < 10; i++) {
    35             es.execute(new Runnable() {
    36                 @Override
    37                 public void run() {
    38                     System.out.println(Singleton3.getInstance());
    39                 }
    40             });
    41         }
    42 
    43         es.shutdown();
    44     }
    45 }

    4.静态内部类的单例模式:也是只会在第一次需要的时候创建对象,以后每次获取该对象的时候后都不会再次创建对象,线程是安全的。

     1 class Singleton4 {
     2     private static class InnerSingletion {
     3         private static Singleton4 single = new Singleton4();
     4     }
     5     
     6     private Singleton4(){
     7         try {
     8             Thread.sleep(1000);
     9             System.out.println("构建这个对象可能耗时很长...");
    10         } catch (InterruptedException e) {
    11             e.printStackTrace();
    12         }
    13     }
    14     
    15     public static Singleton4 getInstance(){
    16         return InnerSingletion.single;
    17     }
    18     
    19     @Override
    20     public String toString() {
    21         return ""+this.hashCode();
    22     }
    23 }
    24 
    25 public class DemoThread25 {
    26     public static void main(String[] args) throws InterruptedException {
    27         ExecutorService es = Executors.newFixedThreadPool(100);
    28         for (int i = 0; i < 10; i++) {
    29             es.execute(new Runnable() {
    30                 @Override
    31                 public void run() {
    32                     System.out.println(Singleton4.getInstance());
    33                 }
    34             });
    35         }
    36 
    37         es.shutdown();
    38     }
    39 }
  • 相关阅读:
    Linux从入门到入门到入门(一)
    计算机网络学习笔记
    计算机网络学习笔记
    c语言数据结构学习心得——排序
    c语言数据结构学习心得——查找
    adb 命令小结
    软件测试之面试题分享
    关于app启动时间测试的小思考
    软件缺陷
    黑盒测试,白盒测试
  • 原文地址:https://www.cnblogs.com/xuzhiyuan/p/9265433.html
Copyright © 2020-2023  润新知