您的当前位置:首页正文

线程池threadpool多线程执行任务提高性能,可以传参和获取返回值

2024-11-25 来源:个人技术集锦

需求

假设现在有一个很大的集合需要进行求和(真实项目中,比如向数据库中插入数据),需要的时间很长,考虑将大集合切分成几个小集合进行同步的求和,在将最终得到的几个结果加起来得到最终的结果。

实现

不多废话,直接上代码,创建一个Task类实现runnable接口,实现run方法。利用Task类的属性进行参数接收,和结果返回。

package com.test.threadpool;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 任务多线程执行管理类
 * @author zcc
 *
 */
public class WorkExecutor
{
    private WorkExecutor()
    {
    }

    private static ExecutorService exectuerService = null;

    static
    {
        // 初始化线程池服务
        exectuerService = Executors.newCachedThreadPool();
    }

    /**
     * 新建线程池
     * @param command
     */
    public static void create()
    {
    	exectuerService = Executors.newCachedThreadPool();
    }

    /**
     * 提交任务<br>
     * 可获取到任务结果
     * @param <T>
     * @param <T>
     * @param task
     * @return
     */
    public static <T> Future<T> submitTask(Callable<T> task)
    {
        return exectuerService.submit(task);
    }

    /**
     * 提交执行批量任务<br>
     * 可获取到任务结果
     * @param <T>
     * @param <T>
     * @param task
     * @return
     * @throws Exception
     */
    public static <T> List<Future<T>> submitTasks(Collection<? extends Callable<T>> tasks) throws Exception
    {
        return exectuerService.invokeAll(tasks);
    }

    /**
     * 执行任务
     * @param command
     */
    public static void executeTask(Runnable task)
    {
        exectuerService.execute(task);
    }

    /**
     * 关闭线程停止服务
     */
    public static void shutdown()
    {
        exectuerService.shutdown();
    }

    /**
     * 是否完成任务
     */
    public static boolean isTerminated()
    {
        return exectuerService.isTerminated();
    }
}

package com.test.threadpool;

import java.util.List;

/**
 * 自定义一个任务执行类,实现runnable接口,实现run方法
 * @author zcc
 *
 */
public class Task  implements Runnable
{

	//传参
	private List<Integer> values;
	//返回值
	private Integer result;
	
	public Task(List<Integer> values) 
	{
		super();
		this.result = 0;
		this.values = values;
	}

	public List<Integer> getValues() {
		return values;
	}

	public void setValues(List<Integer> values) {
		this.values = values;
	}

	public Integer getResult() {
		return result;
	}

	public void setResult(Integer result) {
		this.result = result;
	}

	@Override
	public void run() 
	{
		//传进来一个double集合,将集合的和计算出来
		if (this.values == null || this.values.size() == 0) 
		{
			this.result = 0;
		}else 
		{
			for (Integer value: values) 
			{
				result = result+value;
			}
		}
	}

}

package com.test.threadpool;

import java.util.ArrayList;
import java.util.List;

public class Test 
{
	public static void main(String[] args) throws InterruptedException 
	{
		//假设现在有一个很大的数组需要进行求和,数组量大需要的时间长,使用线程池的方式多线程去计算数据(将原本大数组,分成n个小数组,同时算出个个小数组的和后,在对n个和进行求和)
		List<Integer> originalData = new ArrayList<>();
		for (int i = 0; i < 100; i++) 
		{
			originalData.add(i);
		}
		//一共是100个数,假设100个数需要很长的时间计算,我们进行分组,将100个数分成5组
		List<Integer> subList = originalData.subList(0, 20);
		List<Integer> subList2 = originalData.subList(20, 40);
		List<Integer> subList3 = originalData.subList(40, 60);
		List<Integer> subList4 = originalData.subList(60, 80);
		List<Integer> subList5 = originalData.subList(80, 100);
		Task task = new Task(subList);
		Task task2 = new Task(subList2);
		Task task3 = new Task(subList3);
		Task task4 = new Task(subList4);
		Task task5 = new Task(subList5);
		//创建线程池
		WorkExecutor.create();
		WorkExecutor.executeTask(task);
		WorkExecutor.executeTask(task2);
		WorkExecutor.executeTask(task3);
		WorkExecutor.executeTask(task4);
		WorkExecutor.executeTask(task5);
		//关闭线程池,线程池关闭后,就不能再接收任务了
		WorkExecutor.shutdown();
		
		//判断线程池中所有的任务是否都完成,没有完成就继续等待
		while (!WorkExecutor.isTerminated()) 
		{
			Thread.sleep(100);
		}
		//线程池中所有的任务完成后
		Integer result = task.getResult()+task2.getResult()+task3.getResult()+task4.getResult()+task5.getResult();
	}
}

显示全文