多线程分批处理list

任务类

package com.ultrapower.syn.common;

import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.ultrapower.syn.domain.SynResult;

public class SynTask implements Runnable {
	private final static Logger logger = Logger.getLogger(SynTask.class);
	private List list;
	private String url;
	private String des;

	@Override
	public void run() {
		try {
			long startTime = new Date().getTime();
			logger.info(des + "开始,同步地址:" + url);
			String jsonString = JSONObject.toJSONString(list);
//			 logger.info("同步数据: " + jsonString);
			jsonString = EncryptUtil.encode3Des(jsonString);
			DefaultHttpClient client = new DefaultHttpClient(
					new PoolingClientConnectionManager());
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("STEP", EncryptUtil.encode3Des("2"));
			httpPost.setEntity(new StringEntity(jsonString, Charset
					.forName("UTF-8")));
			CloseableHttpResponse response;
			String responseStr = "";
			response = client.execute(httpPost);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				throw new Exception(des + "同步地址:" + url + ",请求出错: "
						+ statusCode);
			}
			HttpEntity entity = response.getEntity();
			responseStr = EntityUtils.toString(entity, "UTF-8");
			// logger.info("responseStr:"+responseStr);
			String jsonStr = EncryptUtil.decode3Des(responseStr);
			// logger.info("resultStr:"+jsonStr);
			SynResult result = JSONObject.parseObject(jsonStr, SynResult.class);
			if (result != null) {
				List datas = result.getResultInfo();
				int sucessCount = 0;
				int errCount = 0;
				if (datas != null) {
					for (int i = 0; i < datas.size(); i++) {
						JSONObject object = (JSONObject) datas.get(i);
						String errCode = object.getString("errCode");
						if (errCode == null || "".equals(errCode)) {
							sucessCount++;
						} else {
							errCount++;
						}
					}
				} else {
					throw new Exception(des + "同步地址:" + url + ",未获取到同步结果 ");
				}
				long endTime = new Date().getTime();
				int spendTime = (int) ((endTime - startTime) / 1000);
				logger.info(des + "同步完成,sucessCount:" + sucessCount + ","
						+ "errCount:" + errCount + " 耗时:" + spendTime + "s");

			} else {
				// logger.info("同步结果: " + jsonStr);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List getList() {
		return list;
	}

	public void setList(List list) {
		this.list = list;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getDes() {
		return des;
	}

	public void setDes(String des) {
		this.des = des;
	}
}

任务管理类

package com.ultrapower.syn.common;

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

import org.apache.log4j.Logger;

public class ThreadManager {
	private final static Logger logger = Logger.getLogger(ThreadManager.class);
	/**
	 * 放入任务池
	 * @param url
	 * @param list
	 * @param executor
	 * @param des
	 */
	private static void putTask(String url, List list,
			ThreadPoolExecutor executor,String des) {
		SynTask task = new SynTask();
		task.setUrl(url);
		List list2 = new ArrayList();
		list2.addAll(list);
		task.setList(list2);
		task.setDes(des);
		executor.execute(task);
	}

	/**
	 * 多线程分隔并发送数据
	 * @param url
	 * @param list
	 * @throws InterruptedException
	 */
	public static void separateSendData(String url, List list)
			throws InterruptedException {
		if (list == null || list.size() == 0) {
			logger.info("同步数据为空");
			return;
		}
		int maxSynNum = Integer.valueOf(SynConfig.getProperty("maxSynNum"));//每次同步,最大同步数量
		int MAX_THREADS = Integer.valueOf(SynConfig.getProperty("maxThreads"));// 最大线程数
		ThreadPoolExecutor executor = new ThreadPoolExecutor(5, MAX_THREADS,
				10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5),
				new ThreadPoolExecutor.CallerRunsPolicy());

		int size = list.size();
		if (size > maxSynNum) {
			int part = size / maxSynNum;// 分批数
			logger.info("共有 : " + size + "条," + " 分为 :" + (part+1) + "批");
			for (int i = 0; i < part; i++) {
				List newList = list.subList(0, maxSynNum);
				String des = "第" + (i + 1) + "批处理";
				putTask(url, newList, executor,des);
				list.subList(0, maxSynNum).clear();
			}
			if (!list.isEmpty()) {
				String des = "最后一批数据处理";// 表示最后剩下的数据
				putTask(url, list, executor,des);
			}
		} else {
			putTask(url, list, executor,"");
		}
		executor.shutdown();// 手动关闭线程池
		
		while (!executor.isTerminated()) {
			//等待同步完成
			Thread.sleep(1000);
		}
		if (executor.isTerminated()) {
			logger.info(url+"同步已完成");
		}
	}
}

执行方法

ThreadManager.separateSendData(url,list);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 提供了一种方便的方式来处理大量数据,特别是在涉及到批(Batching)或多线程场景时,它结合了Spring框架的强大功能和现代并发编程的最佳实践。以下是使用Spring Boot进行批量多线程处理数据的一种常见策略: 1. **使用Reactor或Stream API**:Spring Boot 5引入了对Reactor和Java Stream的支持,你可以创建流式API来处理数据,这种方式天然适合于批量操作。例如,你可以使用`Flux`或`PipedBuffer`来逐块读取和处理数据。 ```java Flux<DataItem> dataStream = dataRepository.findAllInBatches(batchSize); dataStream.parallel().subscribe(data -> processData(data)); ``` 2. **Spring Batch**:这是一个专门用于批处理任务的模块,可以在Spring Boot项目中集成。它可以让你编写易于维护的批处理作业,管理任务生命周期,包括调度、监控和回滚。 ```java @Bean public ItemReader<DataItem> itemReader() { // 创建数据源读取器 } @Bean public ItemProcessor<DataItem, DataItem> itemProcessor() { // 数据处理逻辑 } @Bean public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { return jobs.get("batchJob") .incrementer(new RunIdIncrementer()) .flow(step1(), step2(), ...) .end() .build(); } @Bean public Step step1(StepBuilderFactory steps) { return steps.get("step1") .<DataItem, DataItem>chunk(batchSize) .reader(itemReader()) .processor(itemProcessor()) .writer(someWriter()) .build(); } ``` 3. **使用ExecutorService**:利用Spring提供的`ThreadPoolTaskExecutor`,你可以创建一个线程池来并发执行多个数据处理任务。 ```java ExecutorService executor = Executors.newFixedThreadPool(10); List<DataItem> dataList = ...; dataList.stream().parallel().forEach(executor::submit, new Consumer<Runnable>() { public void accept(Runnable r) { r.run(); } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值