1 importjava.util.ArrayList;2 importjava.util.Date;3 importjava.util.List;4 importjava.util.Set;5 importjava.util.concurrent.CountDownLatch;6 importjava.util.concurrent.ExecutorService;7 importjava.util.concurrent.Executors;8
9 importorg.apache.commons.logging.Log;10 importorg.apache.commons.logging.LogFactory;11 importorg.hibernate.Session;12 importorg.hibernate.Transaction;13
14
15 importcom.zldb.db.D05DataUser;16 importcom.zldb.util.HibernateUtil;17 importcom.zldb.util.MyDateFormat;18
19 public classThreadDemo {20 private Log log = LogFactory.getLog(ThreadDemo.class) ;21
22 public ListgetList(String userId, String startDate, String endDate) {23 List list = new ArrayList() ;24 Session session =HibernateUtil.getSession() ;25 //多线程并发查询共用一个Session,虽然查询用不到事务,但是需要开始事务
26 Transaction transaction =session.beginTransaction() ;27 try{28 //时间格式化
29 Date start =MyDateFormat.parseDate(startDate) ;30 //由于结束时间格式化结果为例如:2014-03-20 00:00:00 ,所以这天的数据是差不出来的,需要加上一天并减去一毫秒,即是:2014-03-20 23:59:59
31 Date end = new Date(MyDateFormat.parseDate(endDate).getTime() + MyDateFormat.DATEMILLIS -1) ;32 //根据开始时间和结束时间,获取被查询表的集合
33 Set tableSet = MyDateFormat.tableName(startDate, endDate, "D05_Data_User_") ;34 //创建线程池
35 ExecutorService threadPool =Executors.newCachedThreadPool() ;36 //线程池辅助类,控制正在运行的线程总数
37 CountDownLatch latch = newCountDownLatch(tableSet.size()) ;38 //循环查询每张表
39 for(String tableName : tableSet) {40 //创建线程
41 QueryTask task = newQueryTask(session, start, end, userId, tableName, latch, list) ;42 //将线程放入线程池中执行
43 threadPool.execute(task) ;44 }45 //等待线程池中的线程全部执行完毕
46 latch.await() ;47 //关闭线程池
48 threadPool.shutdown() ;49 transaction.commit() ;50 } catch(Exception e) {51 if(transaction != null) {52 transaction.rollback() ;53 }54 e.printStackTrace() ;55 log.error(e.getMessage()) ;56 } finally{57 HibernateUtil.closeSession() ;58 }59 //查询结果的集合需要排序,此处省略掉了
60 returnlist ;61 }62
63 }64
65 class QueryTask implementsRunnable{66 private Log log = LogFactory.getLog(QueryTask.class) ;67
68 privateSession session ;69 privateDate start ;70 privateDate end ;71 privateString userId ;72 privateString tableName ;73 privateCountDownLatch latch ;74 private ListuserList ;75
76 publicQueryTask() {77 super() ;78 }79
80 publicQueryTask(Session session, Date start, Date end, String userId,81 String tableName, CountDownLatch latch, ListuserList) {82 super();83 this.session =session;84 this.start =start;85 this.end =end;86 this.userId =userId;87 this.tableName =tableName;88 this.latch =latch;89 this.userList =userList;90 }91
92 @SuppressWarnings("unchecked")93 @Override94 public voidrun() {95 String sql =
96 " SELECT ID, CreateTime, UsedSpan, OriginalHeatIncrement, Power, HeatIncrement, ChargeIncrement" +
97 " FROM "+tableName+
98 " WHERE UserID = :userId AND CreateTime BETWEEN :start AND :end";99 try{100 //查询一张表的数据
101 List objsList =session.createSQLQuery(sql)102 .setString("userId", userId)103 .setDate("start", start)104 .setDate("end", end)105 .list() ;106 //解析数据,这里并没有查询全部封装到类的属性中,因为我并不需表中每一个字段的数据
107 List list = new ArrayList() ;108 for(Object[] objs : objsList) {109 D05DataUser d05 = newD05DataUser() ;110 d05.setId(Integer.parseInt(objs[0].toString())) ;111 d05.setCreateDate((Date) objs[1]) ;112 d05.setUsedSpan(Integer.parseInt(objs[2].toString())) ;113 d05.setOriginalHeatIncrement(Double.parseDouble(objs[3].toString())) ;114 d05.setPower(Double.parseDouble(objs[4].toString())) ;115 d05.setHeatIncrement(Double.parseDouble(objs[5].toString())) ;116 d05.setChargeIncrement(Double.parseDouble(objs[6].toString())) ;117 list.add(d05) ;118 }119 //这里必须用同步代码块,不然userList中的数据会出现缺失
120 synchronized(userList) {121 userList.addAll(list) ;122 }123 } catch(Exception e) {124 e.printStackTrace() ;125 log.error(e.getMessage()) ;126 } finally{127 //每结束一个线程,就要总数减一
128 latch.countDown() ;129 }130 }131
132 }