单线程和多线程处理1W条数据对比代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单线程和多线程处理1W条数据对比代码相关的知识,希望对你有一定的参考价值。

package study.interview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.Random;
import java.util.Set;



public class TestEmailFromList {
	final static String[] list = {"qq.com","126.com","168.com","sina.com","baidu.com","soho.com","yeah.net","139.com","hotmail.com"};
	public static void main(String[] args) throws InterruptedException {
		//email存放容器
		LinkedList<Email> emailList = new LinkedList<Email>();
		//统计各类邮箱使用人数容器
		Map<String, Integer> mapEmail = new HashMap<String, Integer>();
		//统计各类邮箱使用人数容器
		Map<String, Integer> mapEmailPool = new HashMap<String, Integer>();
		Random random=new Random();
		//email原始邮箱初始化
		for (int i = 0; i < 9999; i++) {
			int num = random.nextInt(9);
			emailList.add(new Email(String.valueOf(i+"@"+list[num])));
		}
		
		// 单线程统计各类邮箱使用人数
		long startTime = System.currentTimeMillis();
		TestEmailFromList.countingBySingleThread(emailList, mapEmail);	
		long endTime = System.currentTimeMillis();
		System.out.println("单线程统计用时:"+(endTime-startTime));
		
		//多线程统计各类邮箱使用人数
		long startTime2 = System.currentTimeMillis();
		//用多少个线程
		TestEmailFromList.countingByMultiThread(emailList, mapEmailPool);
		long endTime2 = System.currentTimeMillis();
		System.out.println("多线程统计用时:"+(endTime2-startTime2));
		
	}
	/*
	 * 单线程统计邮箱使用人数
	 */
	public static void countingBySingleThread(LinkedList<Email> emailList,Map<String, Integer> mapEmail){
		for (int i = 0; i <emailList.size(); i++) {
			String key = emailList.get(i).getUserName().split("@")[1];
			if(mapEmail.containsKey(key)){
				int  value = mapEmail.get(key);
				mapEmail.put(key, ++value);
			}else{
				mapEmail.put(key, 1);
			}
		}
		printMap(mapEmail);
	}
	/*
	 * 多线程统计邮箱使用人数
	 */
	public static  void countingByMultiThread(LinkedList<Email> emailList,Map<String, Integer> mapEmailPool){
		ExecutorService executorService = Executors.newCachedThreadPool(); 
        List<Future<Map<String, Integer>>> resultList = new ArrayList<Future<Map<String, Integer>>>(); 
        for (int i = 0; i < 4; i++) {
        	LinkedList<Email> eList = null;
        	if(i==3){
        		eList = new LinkedList<Email>(emailList.subList(i*2500,(i+1)*2500-1));
        	}else{
        		eList = new LinkedList<Email>(emailList.subList(i*2500,(i+1)*2500));
        	}
        	System.out.println(eList.getFirst().getUserName()+"----"+eList.getLast().getUserName());
            //使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
            Future<Map<String, Integer>> future = executorService.submit(new TaskWithResultMap( eList,mapEmailPool)); 
            //将任务执行结果存储到List中
            resultList.add(future); 
            
        } 

        //遍历任务的结果
        for (Future<Map<String, Integer>> fs : resultList) { 
        	try {
				System.out.println(fs.get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}finally{
				executorService.shutdown();
			}
        }
		
		printMap(mapEmailPool);
	}
	
	/*
	 * 输出map
	 */
	public static void printMap(Map<String, Integer> mapEmail){
		Set<Entry<String, Integer>> set = mapEmail.entrySet();
		for (Entry<String, Integer> entry : set) {
			System.out.println("使用"+entry.getKey()+"的人共"+entry.getValue());
		}
	}

}

class TaskWithResultMap implements Callable<Map<String, Integer>>{
	LinkedList<Email> emailList;
	Map<String, Integer> mapEmailPool;
	public TaskWithResultMap(LinkedList<Email> emailList,Map<String, Integer> mapEmailPool){
		this.emailList = emailList;
		this.mapEmailPool = mapEmailPool;
	}

	@Override
	public Map<String, Integer> call() throws Exception {
		synchronized (mapEmailPool) {
			for (int i = 0; i <emailList.size(); i++) {
				String key = emailList.get(i).getUserName().split("@")[1];
				if(mapEmailPool.containsKey(key)){
					int  value = mapEmailPool.get(key);
					mapEmailPool.put(key, ++value);
				}else{
					mapEmailPool.put(key, 1);
				}
			}
		}
		return mapEmailPool;
	}
	
	
}


class MyThread implements Runnable {
	LinkedList<Email> emailList;
	Map<String, Integer> mapEmailPool;

	public MyThread(LinkedList<Email> emailList,Map<String, Integer> mapEmailPool) {
		this.emailList = emailList;
		this.mapEmailPool = mapEmailPool;
	}

	public void run() {
		while(true){
			synchronized (mapEmailPool) {
				try {
					for (int i = 0; i <emailList.size(); i++) {
						String key = emailList.get(i).getUserName().split("@")[1];
						if(mapEmailPool.containsKey(key)){
							int  value = mapEmailPool.get(key);
							mapEmailPool.put(key, ++value);
						}else{
							mapEmailPool.put(key, 1);
						}
						
					}
				} catch (Exception e) {
					System.out.println(Thread.currentThread().getName()+"异常");
				}
				
			}
		}
	}

	
}

class Email {
	String username;

	public Email() {
	}

	public Email(String username) {
		this.username = username;
	}

	public String getUserName() {
		return username;
	}
}

 

以上是关于单线程和多线程处理1W条数据对比代码的主要内容,如果未能解决你的问题,请参考以下文章

011_Python中单线程多线程和多进程的效率对比实验

单线程多线程和多进程的效率对比实验

Python高阶(一) - 单线程、多线程和多进程的效率对比测试

1.1进程和多线程的概念

Python的多线程和多进程模块对比测试

问:Redis为什么是单线程的