两种多线程查库写法

可以用于excel导出场景

直接上代码:

package com.threadmore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MutiThreadQuery {

    public List<Object> queryMethedOne() {

        ThreadPoolExecutor executor = 
                new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, 
                        new ArrayBlockingQueue<Runnable>(10), 
                        new ThreadPoolExecutor.CallerRunsPolicy());

        System.out.println("start thread pool...");

        List<Object> resultList = new ArrayList<Object>();

        //查询页数(批次)
        int pageIndex = 0;

        int n = 30;//当页数小于n(总线程数)时,跳出

        do {

            MergeRunnable mr = new MergeRunnable(resultList, pageIndex);

            executor.execute(mr);

            System.out.println("pageIndex:"+pageIndex);
            pageIndex++;


        }while(pageIndex < n);//当页数小于n(总线程数)时,跳出

        executor.shutdown();//不能再提交新任务

        boolean loop = true;

        try {
            do {//等待所有任务完成

                System.out.println("线程池中线程数目:" + executor.getPoolSize());

                System.out.println("队列中等待执行的任务数目:" +  executor.getQueue().size());

                System.out.println("已执行完的任务数目:" + executor.getCompletedTaskCount());

                System.out.println("当前的resultList数量:" + resultList.size());

                System.out.println("总共记录数:" + "xxx");

                //阻塞,直到线程池所有的任务结束,2秒判断一次
                loop = !executor.awaitTermination(2, TimeUnit.SECONDS);

            }while(loop);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return resultList;
    }

    class MergeRunnable implements Runnable{

        private List<Object> allRest;

        private int pageIndex;

        public MergeRunnable(List<Object> resultList, int pageIndex) {
            this.allRest = resultList;
            this.pageIndex = pageIndex;
        }

        @Override
        public void run() {
            System.err.println(Thread.currentThread().getName() +" query data start...");
            List<Object> tempPageRest = queryFromDataBase(pageIndex);
            synchronized(allRest) {
                allRest.addAll(tempPageRest);
            }
            System.err.println(Thread.currentThread().getName() +" query data end...");
        }

    }

    private List<Object> queryFromDataBase(int pageIndex) {
        // TODO do some operation from database
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<Object> test = new ArrayList<Object>();
        return test;
    }

    //----------------------------华丽的分割线----以下是第二种写法,为了测试和第一种有没有性能上的差别---------

    public List<Object> queryMethedTwo() {

        ThreadPoolExecutor executor = 
                new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, 
                        new ArrayBlockingQueue<Runnable>(10), 
                        new ThreadPoolExecutor.CallerRunsPolicy());

        System.out.println("start thread pool...");

        List<Object> resultList = new ArrayList<Object>();

        //查询页数(批次)
        int pageIndex = 0;

        int n = 30;//当页数小于n(总线程数)时,跳出

        CountDownLatch latch = new CountDownLatch(n);

        for (int i = 0; i < n; i++) {

            MergeRunnable1 mr1 = new MergeRunnable1(resultList, pageIndex, latch);

            executor.execute(mr1);

            System.out.println("pageIndex:"+pageIndex);
            pageIndex++;

        }

        executor.shutdown();

        try {
            latch.await(2,TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return resultList;

    }

    class MergeRunnable1 implements Runnable{

        private List<Object> allRest;
        private int pageIndex;
        private CountDownLatch latch;

        public MergeRunnable1(List<Object> resultList, int pageIndex, CountDownLatch latch) {
            this.allRest = resultList;
            this.pageIndex = pageIndex;
            this.latch = latch;
        }

        @Override
        public void run() {
            System.err.println(Thread.currentThread().getName() +" query data start...");
            List<Object> tempPageRest = queryFromDataBase(pageIndex);
            synchronized(allRest) {
                allRest.addAll(tempPageRest);
            }
            latch.countDown();
            System.err.println(Thread.currentThread().getName() +" query data end...");
        }

    }

    //----------------------------华丽的分割线----以下是第二种写法,为了测试和第一种有没有性能上的差别---------

    public static void main(String[] args) {

        MutiThreadQuery m = new MutiThreadQuery();

        long a = System.currentTimeMillis();

        m.queryMethedOne();

//      m.queryMethedTwo();

        System.out.println("#################:"+(System.currentTimeMillis() - a)+"ms");

    }


}

之后一篇主要分析多线程包中API使用细节。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值