日期:2014-05-18  浏览次数:20593 次

这样的情况怎么使用多线程来处理?
本帖最后由 matrix1984 于 2013-06-17 18:37:44 编辑
需求:表A里有很多数据,程序需要从表A里取数据,并对每一条数据进行逻辑处理。
如果是单线程,可能是这样的逻辑:

...
...
long start = System.currentTimeMillis();
while(true) {
  DataBean[] beans = queryData(5000); //每次取5000条
  if(beans.length > 0) {
    for(DataBean b:beans) {       //业务处理
      processBean(b);             //业务处理
    }                             //业务处理
  } else break;

  if(beans.length < 5000) break; //没有更多的数据
}
long end = System.currentTimeMillis();
System.out.println("使用时间: " + (end - start) + "ms"); //打印当所有任务都完成时所用时间
...
...

public DataBean[] queryData(int size) {
  //查询数据并返回
}

public void processBean(DataBean b) throws Exception {
  // 处理数据对象b,处理完毕会更新状态(不会再次被处理)
}

由于数据量很大,就想采用多线程/线程池来处理,每次取5000条放到一个线程,最多5个线程,当5个线程都起来了,就等待,任务可以加入队列中,知道有空闲的线程出来。
并且有个要求,只要有线程或者队列有任务,主线程不能结束,直至所有任务都跑完,并打印最终使用的总时间。

上网有看到使用ThreadPoolExecutor来做,但具体到这个例子,该怎么使用呢?请有经验的大大指导一下。


------解决方案--------------------
5个线程取数据,那么数据的处理呢?也使用5个线程吗???
------解决方案--------------------
ThreadPool不是重点,重点是要保证异步线程取bean时,如何并发、互斥的获取数据。

我们可以把beans放到队列或堆栈中,任意线程来了,只取第一个bean(这个“取”操作要synchronized),然后run方法只做单一bean的处理即可。

最后,我们初始化的任意个(LZ这里要求5个就5个吧,其实ThreadPool更适合不定个数个异步线程的处理)线程,使用ThreadPool实例对象(单例)的excute(Runnable r)方法加入到线程池即可。
------解决方案--------------------
楼主你好,看到你这个需求,我想我们是不是可以换个思路。
既然那么多数据都要做处理,不如,我们把这些数据用后台,比如shell程序去处理,将数据后的结果集添加到新的数据库(表)中。这样我们只需要在新的数据库(表)中去读就可以了。
楼主你觉得呢。
------解决方案--------------------
引用: