JAVA 多线程处理多个订单

问题描述:假如客户给你丢过来1000个订单,这些订单都需要1到2秒的处理时间。你怎么以最快的速度完成处理并保存到数据库?

问题解析:设每个运单处理需要1秒的时间。

  1. 以传统的方式去处理,我写个循环,一个订单一个订单地去处理,那么总耗时为:1*1000=1000秒(约等于17个分钟,那客户还不急死?)

  2. 以多线程的方式去处理,1000的个订单我就创建1000个线程去处理,那么总耗时就只有1秒!(很明显,客户喜欢这种方式)

如何实施(因为资源的问题,不能创建1000个线程):

我现在先假设用户丢过来13条数据,由于资源的问题我们只能创建5个线程,那么每个线程应该处理几条数据?

int per = data.size() / 5 = 2,这样一来每个线程只能处理两个,那么还剩下3个怎么办?

package org.java.test4;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class ThreadDemo {

	private static class ProcessDataTask implements Callable<String> {

		private List<String> data = new ArrayList<>();

		public void add(String item) {
			data.add(item);
		}

		@Override
		public String call() throws Exception {
			//处理数据
			for (String item : data) {
				System.out.println(Thread.currentThread().getName() + "-data:" + item);
			}
			
			//模拟数据处理需要1秒钟
			Thread.sleep(1000);
			
			//最后返回你想返回的东西
			return Thread.currentThread().getName();
		}
	}

	public static void main(String[] args) throws Exception {
		//模拟客户数据,假设现在客户上传了13条数据
		List<String> userData = new ArrayList<String>();
		for (int i = 1; i <= 13; i++) {
			userData.add("jackson_" + i);
		}

		//构造线程,假设总的线程数为5个
		int totalThreadNum = 5;
		List<ProcessDataTask> tasks = buildThread(userData, 5);

		//构造线程池,然后执行每一个线程
		ExecutorService executorService = Executors.newFixedThreadPool(totalThreadNum);
		List<Future<String>> threadResults = executorService.invokeAll(tasks);
		executorService.shutdown();
		
		//遍历线程结果
		for (Future<String> future : threadResults) {
			try {
				FutureTask<String> futureTask = (FutureTask<String>) future;
				System.out.println("thread return value: " + futureTask.get());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
	
	/**
	 * 根据数据和线程数为每一个线程分配数据
	 * @param data
	 * @param totalThreadNum
	 * @return
	 * @throws Exception
	 */
	public static List<ProcessDataTask> buildThread(List data, int totalThreadNum) throws Exception {
		int nThreads = totalThreadNum;
		int perThreadDataNum = data.size() / nThreads;
		int remainDataNum = data.size() % nThreads;
		
		List<ProcessDataTask> tasks = new ArrayList<ProcessDataTask>();
		for (int i = 0; i < nThreads; i++) {
			ProcessDataTask processDataTask = new ProcessDataTask();
			Iterator iterator = data.iterator();
			int j = 0;
			while (j < perThreadDataNum && iterator.hasNext()) {
				processDataTask.add((String) iterator.next());
				iterator.remove();
				++j;
			}
			if (remainDataNum > 0) {
				processDataTask.add((String) iterator.next());
				iterator.remove();
				remainDataNum--;
			}
			tasks.add(processDataTask);
		}
		
		return tasks;
	}

}

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值