一種優化操做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),或在評論處留下您的留言。多線程

相關文章
相關標籤/搜索