zoukankan      html  css  js  c++  java
  • 多线程处理pdf附件转换

    业务中要把pdf转为pngs,作以下service

        public PageResult findByUrl(String url) {
            if(!Pdf2Img.checkPdf(url))
                return PageResult.genFail("非pdf文件");
    
            Attach attach = attachDao.findByUrl(url);
    
            if(attach == null) {
                AttachThread mt1=new AttachThread(url);
                new Thread(mt1).start();
                return PageResult.genFail("文件未准备好,请稍后再试");
    
            } else {
                String res = attach.getUrl_new();
                String [] imgs = res.split(",");
                return PageResult.genSuccess((Object)imgs);
            }
        }

    传入pdf文件url,返回pngs文件url,

    首先查找该附件有没有转过过,若转换过,直接返回转换后的url,若没转换过,新建线程进行转换

    然而pdf转换png消耗资源及时间较大,若有两个线程同时请求转换,则会重复转换,浪费资源,故作同步处理如下:


    public class AttachThread implements Runnable {
    
        private String url;
        private static AtomicInteger serailCount = new AtomicInteger(1);
    
        private Integer serial;
    
        public AttachThread(String _url) {
            url = _url;
            serial = serailCount.getAndIncrement();
        }
    
        @Override
        public void run(){
            AttachDao attachDao = (AttachDao)SpringUtil.getBean(AttachDao.class);
            Attach attach = attachDao.findByUrl(url);
            if(attach == null) {
                System.out.println(String.format("线程%d,类锁,所有线程阻塞", serial));
                synchronized (AttachThread.class) {
                    attach = attachDao.findByUrl(url);
                    if(attach == null) {
                        String url_new = Pdf2Img.comeGetIdList(url);
    
                        if(url_new != null || !"".equals(url_new)) {
                            attach = new Attach();
                            attach.setCreate_date(new Date());
                            attach.setUrl_old(url);
                            attach.setUrl_new(url_new);
                            attachDao.save(attach);
                        }
                        System.out.println(String.format("线程%d完成业务,释放类锁,第一线程应该走此路径", serial));
                    } else {
                        System.out.println(String.format("线程%d取得锁之后发现业务已经处理,非第一线程应该走此路径", serial));
                    }
                }
            } else {
                System.out.println(String.format("线程%d已经转换,不用锁,原则上不走此路径", serial));
            }
        }
    }

    AttachDao attachDao = (AttachDao)SpringUtil.getBean(AttachDao.class);

    这一段是在此非spring托管的线程类中调用spring托管的类,详细见

    http://blog.csdn.net/silyvin/article/details/70832415

    http://www.cnblogs.com/vinozly/p/5223147.html


     Attach attach = attachDao.findByUrl(url);
            if(attach == null) {

    如果没有找到转换后的png url,则开启转换程序

     System.out.println(String.format("线程%d,类锁,所有线程阻塞", serial));
                synchronized (AttachThread.class) {
                    attach = attachDao.findByUrl(url);
                    if(attach == null) {
                        String url_new = Pdf2Img.comeGetIdList(url);
    
                        if(url_new != null || !"".equals(url_new)) {
                            attach = new Attach();
                            attach.setCreate_date(new Date());
                            attach.setUrl_old(url);
                            attach.setUrl_new(url_new);
                            attachDao.save(attach);
                        }
                        System.out.println(String.format("线程%d完成业务,释放类锁,第一线程应该走此路径", serial));
                    } else {
                        System.out.println(String.format("线程%d取得锁之后发现业务已经处理,非第一线程应该走此路径", serial));
                    }
                }

    开启同步,同步块中,第一线程,再次判断是否转换,其他线程阻塞


    测试,同时进行4次请求,输出


    线程1,类锁,所有线程阻塞

    线程2,类锁,所有线程阻塞

    线程3,类锁,所有线程阻塞

    线程4,类锁,所有线程阻塞

    线程1完成业务,释放类锁,第一线程应该走此路径

    线程4取得锁之后发现业务已经处理,非第一线程应该走此路径

    线程3取得锁之后发现业务已经处理,非第一线程应该走此路径

    线程2取得锁之后发现业务已经处理,非第一线程应该走此路径






  • 相关阅读:
    Elasticsearch 入门教程
    Spring Boot集成JasperReports生成PDF文档
    Java程序员须知的七个日志管理工具
    vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
    spring boot项目在外部tomcat环境下部署
    linux 如何正确的关闭mongodb
    Centos7下yum安装配置nginx与php
    Centos7 搭建lnmp环境 (centos7+nginx+MySQL5.7.9+PHP7)
    CentOS7安装MySQL
    搭建MySQL高可用负载均衡集群(转)
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106807.html
Copyright © 2011-2022 走看看