kkFileView(七)关键代码分析(6)

2021SC@SDUSC

消费队列中转换文件分析

 分析这几个类,消费队列中转换文件有关的代码。

(一)线程池方法

在FileConvertQueueTask类中,先定义了startTask()方法,在spring容器启动后,开始从消费队列中获取文件并转换。

 @PostConstruct
    public void startTask(){
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.submit(new ConvertTask(previewFactory, cacheService, fileUtils));
        logger.info("队列处理文件转换任务启动完成 ");
    }

ExecutorService是Java中对线程池定义的一个接口,它java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法。Java API对ExecutorService接口的实现有两个,所以这两个即是Java线程池具体实现类。除此之外,ExecutorService还继承了Executor接口(注意区分Executor接口和Executors工厂类),这个接口只有一个execute()方法。

submit(Runnable)可以返回一个Future对象,通过返回的Future对象,我们可以检查提交的任务是否执行完毕。如果任务执行完成,future.get()方法会返回一个null。注意,future.get()方法会产生阻塞。此时的submit传入的是一个ConvertTask对象。这个类是为了实现转换的任务。

使用完成ExecutorService之后应该关闭它,否则它里面的线程会一直处于运行状态。程序中的ExecutorService没有关闭,这个应用将一直运行。之所以会出现这种情况,是因为ExecutorService中运行的线程会阻止JVM关闭。如果要关闭ExecutorService中执行的线程,我们可以调用ExecutorService.shutdown()方法。在调用shutdown()方法之后,ExecutorService不会立即关闭,但是它不再接收新的任务,直到当前所有线程执行完成才会关闭,所有在shutdown()执行之前提交的任务都会被执行。如果我们想立即关闭ExecutorService,我们可以调用ExecutorService.shutdownNow()方法。这个动作将跳过所有正在执行的任务和被提交还没有执行的任务。但是它并不对正在执行的任务做任何保证,有可能它们都会停止,也有可能执行完成。

(二)转换任务类

由于要使用线程池,ConvertTask静态类实现了Runnable接口。

初始化:

 private final Logger logger = LoggerFactory.getLogger(ConvertTask.class);

        private final FilePreviewFactory previewFactory;

        private final CacheService cacheService;

        private final FileUtils fileUtils;

        public ConvertTask(FilePreviewFactory previewFactory,
                           CacheService cacheService,
                           FileUtils fileUtils) {
            this.previewFactory = previewFactory;
            this.cacheService = cacheService;
            this.fileUtils=fileUtils;
        }

run方法中:

public void run() {
            while (true) {
                String url = null;
                try {
                    
                    url = cacheService.takeQueueTask();
                    if(url != null){
                       
                        FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
                        FileType fileType = fileAttribute.getType();
                        logger.info("正在处理预览转换任务,url:{},预览类型:{}", url, fileType);
                        if(fileType.equals(FileType.compress) || fileType.equals(FileType.office) || fileType.equals(FileType.cad)) {
                            FilePreview filePreview = previewFactory.get(fileAttribute);
                            filePreview.filePreviewHandle(url, new ExtendedModelMap(), fileAttribute);
                        } else {
                            logger.info("预览类型无需处理,url:{},预览类型:{}", url, fileType);
                        }
                    }
                } catch (Exception e) {
                    try {
                        Thread.sleep(1000*10);
                    } catch (Exception ex){
                        ex.printStackTrace();
                    }
                    logger.info("处理预览转换任务异常,url:{}", url, e);
                }
            }
        }

cacheService.takeQueueTask()方法,从缓存中读取待转换队列。

下面的文件类型转换方法,实现逻辑与文件预览大部分一致。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值