Java多线程导出,单线程压缩

1.客户端网页下载文件, 如果文件比较大,后台要进行压缩在传输给客户端。

2.后台进行压缩以后,要保存到服务器硬盘上, 当下次请求下载,则直接传输。

3.当请求下载的压缩文件不存在,需要查询数据,生成csv,最后将多个文件进行压缩保存到服务器硬盘上。

4.多线程进行查询,单线程进行压缩。

先看一个方法:

       public String accountingVerificationExport(String zipFileName) {
		String zipSrc = "";
		try {
			/**
			 * 导出到本地, 然后压缩成zip,并返回zip文件地址
			 */
			zipSrc = exportToLocation(zipFileName);
		} catch(Exception ex) {
			LOGGER.info("exec accountingVerificationExport error.{}", ex.getMessage());
		}
		return zipSrc;
	}
方法的参数zipFileName是指定压缩之后文件名.exportLocation

        /**
	 * 启动四个线程,同步导出
	 * @param zipFileName
	 * @return
	 */
	private String exportToLocation(String zipFileName) {
		ResourceLoadUtil rlu = new ResourceLoadUtil("/hx.properties");
		final Properties prop = rlu.getProp();
		final String exportLocation = prop.getProperty("hx.export.location.href");
		
		final CountDownLatch end = new CountDownLatch(4);		//子线程
		
		final String [] typeName = new String[]{"receipt","output1","output2","back"};
		final List fileSrcs = new ArrayList();// 用于存放生成的文件名称
		final SessionFactory sessionFactory = accountingVerificationDao.getSessionFactory();
		
		LOGGER.info("导出线程开始运行 !");
		
		for(int i = 0; i < typeName.length; i++) {
			final int index = i;
			new Thread(new Runnable() {
				public void run() {
					LOGGER.info("启动子线程{}", typeName[index]);
					/**
					 * 子线程等待
					 */
					boolean participate = ConcurrentUtil.bindHibernateSessionToThread(accountingVerificationDao.getSessionFactory());
					String fileSrc1 = exportList(exportLocation,prop.getProperty("hx.export."+typeName[index]+".fileName"),
							prop.getProperty("hx.export."+typeName[index]+".sheetColumn"),
							prop.getProperty("hx.export."+typeName[index]+".sql"));
					if(!StringUtil.isEmpty(fileSrc1)) {
						fileSrcs.add(fileSrc1);
					}
					ConcurrentUtil.closeHibernateSessionFromThread(participate, sessionFactory); 
					end.countDown();
					LOGGER.info("{} 线程结束运行.",typeName[index]);
				}
			}).start();
		}
		try {
			end.await();
		} catch (InterruptedException e) {
			LOGGER.info("{}",e.getMessage());
		}
		LOGGER.info("导出线程结束运行 !");
		String zipSrcName = "";
		if(!CollectionUtil.isEmpty(fileSrcs) && fileSrcs.size() > 0) {
			zipSrcName = exportLocation + "/" + zipFileName + ".zip";
			File zip = new File(zipSrcName);// 压缩文件
			File srcfile[] = new File[fileSrcs.size()];  
	        for (int i = 0, n = fileSrcs.size(); i < n; i++) {  
	            srcfile[i] = new File(fileSrcs.get(i));  
	        }  
	        FileZip.ZipFiles(srcfile, zip); 
		}
		return zipSrcName;
	}

CountDownLatch和SessionFactory/ConcurrentUtil.bindHibernateSessionToThread

CountDownLatch: 作用是启动多个线程,主线程等待所有线程完成在执行

ConcurrentUtil.bindHibernateSessionToThread: 最多线程情况下为每个线程绑定session(只有绑定了session才可以用spring的dao bean)

         /**
	 * 导出csv文件,csv没有文件行数限制
	 * @param exportLocation 输出到硬盘的临时地址
	 * @param fileName 文件名
	 * @param titles 标题
	 * @param sql
	 * @return
	 */
	private String exportList(String exportLocation, String fileName, String titles, String sql) {
		String fileSrc = exportLocation + "/" + fileName + ".csv";
		List list = accountingVerificationDao.queryList(sql);//查询到货接收
		FileOutputStream out=null;
        OutputStreamWriter osw=null;
        BufferedWriter bw=null;
        boolean isSucess=false;
        try {
            out = new FileOutputStream(new File(fileSrc));
            osw = new OutputStreamWriter(out);
            bw =new BufferedWriter(osw);
            bw.append(titles).append("\r");//标题
            if(!CollectionUtil.isEmpty(list) && list.size() > 0) {
                for(Object obj : list){
                	String data = (String) obj;
                	if(!StringUtil.isEmpty(data)) {
                		data = data.replaceAll("[\\n\\r\"]", "");
                		data = data.replaceAll("[,]", ",");
                		data = data.replace("@#$%&", ",").trim();
                		bw.append(data).append("\r");
                	}
                }
                isSucess=true;
            }
        } catch (Exception e) {
            isSucess=false;
        }finally{
            if(bw!=null){
                try {
                    bw.close();
                    bw=null;
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
            if(osw!=null){
                try {
                    osw.close();
                    osw=null;
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
            if(out!=null){
                try {
                    out.close();
                    out=null;
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
        }
		if(isSucess) {
			return fileSrc;
		}
		return null;
	} 
  
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * HIbernate子线程中绑定session
 * @author Administrator
 *
 */
public class ConcurrentUtil {
	public static boolean bindHibernateSessionToThread(SessionFactory sessionFactory) {  
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {  
            // Do not modify the Session: just set the participate flag.  
            return true;  
        } else {  
            Session session = sessionFactory.openSession();  
            session.setFlushMode(FlushMode.MANUAL);  
            SessionHolder sessionHolder = new SessionHolder(session);  
            TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);  
        }  
        return false;  
    }  


    public static void closeHibernateSessionFromThread(boolean participate, Object sessionFactory) {  
      
        if (!participate) {  
            SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);  
            SessionFactoryUtils.closeSession(sessionHolder.getSession());  
        }  
    }  
}



你可能感兴趣的:(Spring,javaWeb)