一种优化操做list、数组的多线程解决方案。

这几天接触到了一些操做list的功能,因为list太长,加上每条数据的处理时间,致使性能降低,正好利用学来的多线程知识和网上的资料结合实践一番,写出了一个通用类以下。java

/**
 * 操做数组的线程
 *
 * @author 80004133
 */
public abstract class OperateListThread{
    /**
     * 核心数组,用户须要操做的数组
     */
    public Object[] arr;

    private static final Logger logger = LoggerFactory.getLogger(OperateListThread.class);
    /**
     * 操做数组线程的数量,默认为5
     */
    private int threadNum = 5;

    ExecutorService exec;

    public OperateListThread(List obj, int threadNum){
        this.arr = obj.toArray();
        this.threadNum = threadNum;
        exec = Executors.newFixedThreadPool(threadNum+1);
    }

    /**
     * 获取操做数组后的结果
     * <p>
     *     有返回结果时重写该方法
     * </p>
     * @return
     */
    public Object getResult(){
        return null;
    };

    /**
     * 用户须要实现的方法
     * <p>
     *     表明用户但愿作什么事情,该方法被run方法调用,须要用户实现
     * </p>
     */
    public abstract void doRun(int index);

    /**
     * 调用此方法开始工做
     * @throws InterruptedException
     */
    public void doWork() throws InterruptedException {
        logger.info("Work start ------");
        long start = System.currentTimeMillis();
        int length = arr.length;
        CountDownLatch latch = new CountDownLatch(arr.length % threadNum == 0 ? threadNum : threadNum+1);
        logger.info("length:" + length + ":" + "latch:" + latch.getCount());
        for (int j = 0; j < length; j += length / threadNum) {
            MyThread m = null;
            if ((j + (length / threadNum)) <= length) {
                m = new MyThread(arr, j, j + length / threadNum, latch);
            } else {
                m = new MyThread(arr, j, length, latch);
            }
            exec.execute(m);
        }
        latch.await();
        exec.shutdown();
        logger.info("Spand time:" + (System.currentTimeMillis() - start));
        logger.info("Work end -------");
    }

    public class MyThread implements Runnable {
        Object[] arr;
        int startIndex;
        int endIndex;
        CountDownLatch latch;
 
        public MyThread(Object[] arr, int startIndex, int endIndex, CountDownLatch latch) {
            this.arr = arr;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.latch = latch;
        }
 
        @Override
        public void run() {
            for (int i = startIndex; i < endIndex; i++) {
                //要作的事
                doRun(i);
            }
            logger.info(Thread.currentThread().getName());
            latch.countDown();
        }
    }


    public static void main(String[] args) throws InterruptedException{
        List<Integer> arr = new ArrayList<>();
        for (int i = 1; i <= 10000; i++) {
            arr.add(i);
        }
//      int sum = 0;
//      for (int a: arr) {
//          sum += a;
//      }
//      System.out.println(sum);
        OperateListThread op = new OperateListThread(arr, 5) {
            public int sum = 0;

            public Object getResult() {
                return sum;
            }

            @Override
            public void doRun(int index) {
                sum += (int) arr[index];
            }
        };
        op.doWork();
        int result = (int)op.getResult();
        System.out.println(result);
    }
}

main方法举了一个很简单的使用实例,计算1+2+3+...+10000的和。这个通用类是一个抽象类,用法是实现这个抽象类,并只须要实现简单的doRun()方法,这个方法主要是对list作什么样的操做,index表明当前数组的位置,核心数组为arr。若你须要获得返回值,能够重写getResult()方法来获取返回值。数组

固然,有更好的方案或能够改正的地方欢迎联系我(QQ:2470244153),或在评论处留下您的留言。多线程

相关文章
相关标签/搜索