zoukankan      html  css  js  c++  java
  • 单例模式

    适用场景:
    单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:
    1.需要频繁实例化然后销毁的对象。
    2.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
    3.有状态的工具类对象。
    4.频繁访问数据库或文件的对象。


    以下都是单例模式的经典使用场景:
    1.资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
    2.控制资源的情况下,方便资源之间的互相通信。如线程池等。

    demo代码:

     1 
    /**
    * 使用单例模式获取日志文件的实例对象,避免了一个文件多次被打开造成的异常
    * 文件只能被一个进程打开。改进:使用工厂方法来创建文件实例对象,周期线程池来进行资源的释放
    */

    public class FileOperate { 2 private static String filePath="D:/test/file.log"; 3 4 //volatile 保证赋值执行的有序性,不会出现fileOutputStream已有分配空间但还没实例对象初始化的情况 5 private static volatile FileOutputStream fileOutputStream=null; 6 public static synchronized FileOutputStream getInstance(){//synchronized保证即便执行线程中断也持有锁 7 if(fileOutputStream==null){ 8 File file=new File(filePath); 9 try{ 10 if(!file.exists()){ 11 file.createNewFile(); 12 } 13 fileOutputStream=new FileOutputStream(file,true); 14 }catch (Exception e){ 15 e.printStackTrace(); 16 } 17 } 18 return fileOutputStream; 19 } 20 21 public static synchronized void fileWrite(String content){ 22 System.out.println("执行:"+Thread.currentThread().getName()); 23 FileOutputStream fileOutputStream=getInstance(); 24 try{ 25 byte[] bytes=content.getBytes("utf-8"); 26 fileOutputStream.write(bytes); 27 fileOutputStream.flush(); 28 }catch (IOException e){ 29 e.printStackTrace(); 30 } 31 finally { 32 System.out.println(Thread.currentThread().getName()+"执行完毕"); 33 } 34 } 35 36 public static void main(String[] args) { 37 ExecutorService executorService= Executors.newFixedThreadPool(2); 38 for (int i=0;i<5;i++){ 39 Thread thread=new Thread(){ 40 public void run(){ 41 fileWrite(Thread.currentThread().getName()+":"+UUID.randomUUID().toString()+" "); 42 } 43 }; 44 executorService.execute(thread); 45 } 46 executorService.shutdown(); 47 } 48 49 }

    日志代码优化:

    
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.UUID;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    
    /**
     * 使用单例模式获取日志文件的实例对象,避免了一个文件多次被打开造成的异常
     *
     */
    public class FileOperateOptimize implements Runnable {
        private  String filePath="";
    
        private FileFactory fileFactory=null;
        public FileOperateOptimize(String filePath){
            this.fileFactory=fileFactory;
            this.filePath=filePath;
        }
    
        //volatile 保证赋值执行的有序性,不会出现fileOutputStream已有分配空间但还没实例对象初始化的情况
        private  volatile FileOutputStream fileOutputStream=null;
        public  synchronized FileOutputStream getInstance(){//synchronized保证即便执行线程中断也持有锁
            if(fileOutputStream==null){
                File file=new File(filePath);
                try{
                    if(!file.exists()){
                        file.createNewFile();
                    }
                    fileOutputStream=new FileOutputStream(file,true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            return fileOutputStream;
        }
    
        public  synchronized void  fileWrite(String content){
            System.out.println("执行:"+Thread.currentThread().getName());
            FileOutputStream fileOutputStream=getInstance();
            try{
                byte[] bytes=content.getBytes("utf-8");
                fileOutputStream.write(bytes);
                fileOutputStream.flush();
            }catch (IOException e){
                e.printStackTrace();
            }
            finally {
                System.out.println(Thread.currentThread().getName()+"执行完毕");
            }
        }
    
        public void run(){
            try {
                fileOutputStream.close();
                FileFactory.remove(filePath);
            }catch (Exception e){
                e.printStackTrace();
            }
    
        }
    
    
    }
            import java.util.Map;
            import java.util.concurrent.*;
    
    
    public class FileFactory{
        private static Map<String,FileOperateOptimize> hashMap=new ConcurrentHashMap();//保存文件输入流
    
        private static ScheduledExecutorService executorService=Executors.newScheduledThreadPool(5);
    
        public static FileOperateOptimize newFileOperateOptimize(String filePath) {
            if(hashMap.get(filePath)!=null){
                return hashMap.get(filePath);
            }else {
                FileOperateOptimize fileOperateOptimize= new FileOperateOptimize(filePath);
                hashMap.put(filePath,fileOperateOptimize);
                executorService.schedule(fileOperateOptimize,3, TimeUnit.MINUTES);//超过一定时间对资源释放
                return fileOperateOptimize;
            }
    
        }
    
        public static void remove(String filePath){//访问者模式
            hashMap.remove(filePath);
        }
    }
    import java.util.Date;
    import java.util.UUID;
    
    
    public class Test {
        public static void main(String[] args) {
            String path1="D:/test/file1.log";
            String path2="D:/test/file2.log";
            for(int i=0;i<100;i++){
                FileFactory.newFileOperateOptimize(path1).fileWrite(i+":"+new Date().toString()+":"+ UUID.randomUUID().toString()+"
    ");
                FileFactory.newFileOperateOptimize(path2).fileWrite(i+":"+new Date().toString()+":"+ UUID.randomUUID().toString()+"
    ");
            }
        }
    }
  • 相关阅读:
    LayoutInflater(布局服务)
    FOTA升级
    APK安装过程及原理详解
    Context类型
    Android应用的persistent属性
    Notification(状态栏通知)详解
    Handler消息传递机制浅析
    Selenium HTMLTestRunner 无法生成测试报告的总结
    【python】远程使用rsa登录sftp,上传下载文件
    02.性能测试中的指标
  • 原文地址:https://www.cnblogs.com/qizhufeitian/p/12963680.html
Copyright © 2011-2022 走看看