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

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 }
原文地址:https://www.cnblogs.com/xuzhiyuan/p/9265433.html