zoukankan      html  css  js  c++  java
  • 一种优化操作list、数组的多线程解决方案。

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

    /**
     * 操作数组的线程
     *
     * @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),或在评论处留下您的留言。

  • 相关阅读:
    hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
    bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
    codevs 1191 树轴染色 线段树区间定值,求和
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
    tyvj:1038 忠诚 线段树 区间查询
    KL散度
    NumPy 从已有的数组创建数组
    NumPy 创建数组
    NumPy 数组属性
    NumPy 数据类型
  • 原文地址:https://www.cnblogs.com/sean-zeng/p/11842123.html
Copyright © 2011-2022 走看看