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


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

      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+"	");
     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+"	");
     91         }
     92     }
     93 }
     94 /*
     95 A走到这里,时间片到期,该B运行
     96 B执行完毕了,此时obj对象是B线程new出来的
     97 此时B执行完毕,A又运行,由于是从此处时间片到期,恢复运行后,还从当前行继续
     98 执行下面的代码,A线程又创建了一个对象
     99 此时B创建了一次,A创建了一次,外面最少是两个对象
    100 */
  • 相关阅读:
    Android SD卡读写文件
    Android 是什么
    Canvas 类
    Java IO流之字节流 FileInputStream
    Android中asset文件夹和raw文件夹区别
    随手收藏
    Java IO流
    Android私有文件资源文件的存取
    ubuntu 下的jdk安装
    Paint类
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4005118.html
Copyright © 2020-2023  润新知