利用队列+多线程实现文档在线转换:
主意:为什么要用 队列+线程 ,因为openoffice的转换任务,如果文档过大,多次调用转换就会卡掉,再次利用队列,在转换的过程中其他转换任务处于队列的等待状态,只有转换成功后再调用下个转换任务
第一步:创建一个线程池,(上篇博客有写)
- package com.cloud.job;
-
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- /**
- *
- * @ClassName: ThreadPool
- * @author caixl
- * @date 2016-6-3 下午4:50:00
- *
- */
- public class ThreadPool {
- private static ExecutorService threadPool = null;
- public static ExecutorService getThreadPool(){
- if(threadPool==null){
- threadPool = Executors.newCachedThreadPool();
- }
- return threadPool;
- }
-
- }
第二步:创建一个无界队列(上篇博客有写)
- package com.cloud.job;
-
- import java.util.concurrent.LinkedBlockingQueue;
- /**
- *
- * @ClassName: TaskQueue
- * @author caixl
- * @date 2016-6-3 下午4:49:50
- *
- */
- public class TaskQueue {
- private static LinkedBlockingQueue queues = null;
-
- public static LinkedBlockingQueue getTaskQueue(){
- if(queues==null){
- queues = new LinkedBlockingQueue();
- System.out.println("初始化 队列");
- }
- return queues;
- }
-
- public static void add(Object obj){
- if(queues==null)
- queues = getTaskQueue();
- if(!queues.contains(obj))
- queues.offer(obj);
- System.out.println("-------------------------------");
- System.out.println("入队:"+obj);
- }
- }
第三步:创建一个入队的线程,专门负责往队列中加入元素
- package com.cloud.job;
- /**
- *
- * @ClassName: Produce
- * @author caixl
- * @date 2016-6-3 下午4:49:41
- *
- */
- public class Produce implements Runnable {
- private static volatile boolean isRunning=true;
- private static volatile Object obj;
- public Produce(Object obj){
- this.obj = obj;
- }
- public void run() {
- TaskQueue.add(obj);
- }
-
- }
第四步:创建一个消费的线程,次线程主要负责阻塞作用,也就是转换任务转换任务是否已完成,如果完成调用下一次转换
- package com.cloud.job;
-
- import org.apache.log4j.Logger;
-
- import com.cloud.platform.DocConstants;
- /**
- *
- * @ClassName: Consumer
- * @author caixl
- * @date 2016-6-3 下午4:48:46
- *
- */
- public class Consumer implements Runnable {
- private static Consumer consumer;
- private static Logger logger = Logger.getLogger(Consumer.class);
- public static volatile boolean isRunning=true;
- public void run() {
- while(isRunning)
- {
- isRunning = false;
- DocCovertThread docCovertThread = new DocCovertThread();
- docCovertThread.run();
- }
-
- }
- public static Consumer getInstance(){
- if(consumer==null){
- consumer = new Consumer();
- System.out.println("初始化消费线程");
- logger.info("初始化消费线程");
- }
- return consumer;
- }
-
- }
第五步:创建一个转换文档的线程
- package com.cloud.job;
-
- import java.io.File;
- import java.util.Map;
-
- import org.apache.log4j.Logger;
- import org.artofsolving.jodconverter.OfficeDocumentConverter;
- import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
- import org.artofsolving.jodconverter.document.DocumentFormat;
- import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
- import org.artofsolving.jodconverter.office.OfficeManager;
- import org.quartz.JobExecutionContext;
-
- import com.cloud.doc.convert.pdf2swf;
- import com.cloud.platform.DocConstants;
- import com.database.bean.MainTableAttachFile;
- /**
- *
- * @ClassName: DocCovertThread
- * @author caixl
- * @date 2016-6-3 下午4:49:15
- *
- */
- public class DocCovertThread implements Runnable{
- private static Logger logger = Logger.getLogger(DocCovertThread.class);
- /**
- * openoffice的安装路径
- */
- public static final String OPENOFFICE_HOME = DocConstants.ROOTPATH + "include/OpenOffice";
- @Override
- public void run() {
-
- try {
- JobExecutionContext context = (JobExecutionContext)TaskQueue.getTaskQueue().take();
- System.out.println("出队"+context);
- Map data = context.getJobDetail().getJobDataMap();
- MainTableAttachFile attach = (MainTableAttachFile)data.get("attach");
- if (attach == null) {
- return;
- }
- if (DocConstants.isOffice(com.common.StringHelper.getFileExt(attach.getAttachFileName())))
- {
- System.out.println("开始转换文件"+OPENOFFICE_HOME+" " +attach.getPath());
- DefaultOfficeManagerConfiguration config = new DefaultOfficeManagerConfiguration();
- config.setOfficeHome(OPENOFFICE_HOME);
- OfficeManager officeManager = config.buildOfficeManager();
- try
- {
- officeManager.start();
- OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
- DocumentFormat outputFormat = new DefaultDocumentFormatRegistry().getFormatByExtension("pdf");
-
- String srcPath = attach.getPath();
- String destPath = com.common.StringHelper.getFileName(srcPath) + ".pdf";
-
- converter.convert(new File(srcPath), new File(destPath), outputFormat);
- String docPath = com.common.StringHelper.getFileName(attach.getPath());
- pdf2swf swfConverter = pdf2swf.getInstance();
- swfConverter.convert(docPath, "");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- logger.error("***** 异常信息 ***** 方法:switchDocToSwf at switch office to pdf", e); return;
- }
- finally
- {
- officeManager.stop();
- Consumer.isRunning=true;
- }
- System.out.println("转换结束");
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- Consumer.isRunning=true;
- logger.error("***** 异常信息 ***** 方法:DocConvertJob execute", e);
- }
- }
-
- }
第六步:在需要转换文档时调用
- ExecutorService threadPool = ThreadPool.getThreadPool();
- Produce consumer2 = new Produce(context);
- threadPool.execute(consumer2);
- Consumer consumer=Consumer.getInstance();
- threadPool.execute(consumer);
源码详见:https://github.com/izhbg/typz
|