首页 > 代码库 > [设计模式]单例模式(考虑多线程)

[设计模式]单例模式(考虑多线程)

下面这个程序老师写的,比较经典,现在忘了. 先保存下来.

  1 import java.util.ArrayList;  2   3 public final class SingletonObject {  4     private static SingletonObject obj;  5     private SingletonObject(){}  6     //如果在方法上声明同步,会成为系统并发访问的瓶颈  7     public static SingletonObject getInst(){  8         if(obj == null){  9             synchronized("aa"){ 10                 if(obj == null){ 11                     obj = new SingletonObject(); 12                 } 13             } 14         } 15         return obj; 16     } 17  18     //1.将对象声明到类中作为类变量,初始化 19     //违反了第一条 20     //2.1.将对象声明到类中作为类变量,且不初始化 21     //在static中初始化 22     //总要有一个初始化的代码,写到哪里?如果写到static代码块中,那么类加载时,就会被执行,和直接写obj2 = ....一样的 23     //上述方案违反了下面的第一条 24     //2.2.将对象声明到类中作为类变量,且不初始化 25     //将初始化写入到获取对象的方法中 26     //obj2 = new SingletonObject(); 27     //上述方案违反了下面的第二条 28     //2.2.1.将对象声明到类中作为类变量,且不初始化 29     //在获取方法中进行null的判定,进行初始化 30     //上述方案违反了下面的第三条 31     //最终方案:既要进行对象的一次初始化,又不能将该初始化语句放入到获取方法中 32     //Java中哪种方案是归属于类的模型体系下的且只执行一次,且在类加载时不进行加载,但是使用时才进行加载,那么这个方案就是最终方案 33     //内部类解决方案 34      35     private static class Inner{ 36         //将对象初始化的操作加入到内部类中 37         private static final SingletonObject obj2 = new SingletonObject(); 38     } 39      40     public static SingletonObject getInst2(){ 41         //既需要延迟加载,不使用不创建 42         //又要保障创建的时候不会被多次创建,做成单例 43         //又要求每次获取的时候最好不做null判定 44         return Inner.obj2; 45     } 46      47     public static void main2(String[] args) { 48         System.out.println(SingletonObject.getInst()); 49         System.out.println(SingletonObject.getInst()); 50         System.out.println(SingletonObject.getInst()); 51     } 52      53     public static void main(String[] args) { 54          55         long t1 = System.currentTimeMillis(); 56         long start = 90000000000000001L; 57         long end = 90000000000000100L; 58         long refMax = (long)Math.sqrt(end); 59         ArrayList<Long> primes = new ArrayList<Long>(); 60         OUT: 61         for(long i = 2;i <= refMax ; i++){ 62             for(long j = 2;j<= Math.sqrt(i);j++){ 63                 if(i % j == 0){ 64                     continue OUT; 65                 } 66             } 67             primes.add(i); 68         } 69         System.out.println("end"); 70         OUT: 71         for(long i = start;i<=end;i++){ 72             for(Long prime:primes){ 73                 if(i % prime == 0){ 74                     continue OUT; 75                 } 76             } 77             System.out.print(i+"\t"); 78         } 79         long t2 = System.currentTimeMillis(); 80         System.out.println(t2-t1); 81          82          83         OUT: 84         for(int i = 101;i <= 200 ; i++){ 85             for(int j = 2;j<= Math.sqrt(i);j++){ 86                 if(i % j == 0){ 87                     continue OUT; 88                 } 89             } 90             System.out.print(i+"\t"); 91         } 92     } 93 } 94 /* 95 A走到这里,时间片到期,该B运行 96 B执行完毕了,此时obj对象是B线程new出来的 97 此时B执行完毕,A又运行,由于是从此处时间片到期,恢复运行后,还从当前行继续 98 执行下面的代码,A线程又创建了一个对象 99 此时B创建了一次,A创建了一次,外面最少是两个对象100 */

 

[设计模式]单例模式(考虑多线程)