单线程和多线程处理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;
	}
}
时间: 2024-08-24 05:28:48

单线程和多线程处理1W条数据对比代码的相关文章

TXT创建写入,每个文件允许1W条数据。超过1W条数据分割成多个文件

数据量太大,不想每个文件存入过多的数据量怎么办? 规定文件中数据条数是个好办法,那当你在TXT文件中写入数据,怎么保证数据不超过规定条数?超过的又怎么存到另一个TXT文件里面? 下面我就给你介绍一种简单的方法(当然不排除有更好的,我这种算是仅供参考) 1 if ((icount % 10000 == 0) && (icount / 10000 > 0)) 2 { 3 sw.Close(); 4 flag = flag + icount / 10000; 5 path = outpat

JAVA笔记-如何向Excel表单中高效的批量写入百万条数据

今天,一朋友问我使用JAVA有没有什么办法导出百万级的数据到Excel工作表. 当时我的第一个念头就是这真的是一个好疯狂的念头.然后就想假如真的有这样类似的需求,我自己应该怎么做呢? ps: 首先科普一下基础知识 Excel 2003及以下的版本.一张表最大支持65536行数据,256列.也就是说excel2003完全不可能满足百万数据导出的需求. Excel 2007-2010版本.一张表最大支持1048576行,16384列: 笔者使用的是office 2010,更高的版本笔者没有使用过,暂

Mybatis 批量插入多条数据,使用场景:导入多条数据

Mybatis 批量插入多条数据,使用场景:导入多条数据 接口代码: void batchInsertCapacity(@Param("list")List<Map<String, Object>> metadbmaplist); SQL: <insert id="batchInsertCapacity"> insert into index_prodcut ( ID, ORG_ID, TEXT1, TEXT2, TEXT3, P

json代码驾照考题批量加入MySQL数据库 ps.executeUpdate()永远只能悲催的加一条数据 去掉id主键自增 for 与 foreach

package com.swift; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; im

Redis各种数据结构性能数据对比和性能优化实践

很对不起大家,又是一篇乱序的文章,但是满满的干货,来源于实践,相信大家会有所收获.里面穿插一些感悟和生活故事,可以忽略不看.不过听大家普遍的反馈说这是其中最喜欢看的部分,好吧,就当学习之后轻松一下. Redis各种数据结构性能数据对比 测试工具:perf4j 性能指标:平均值,最小值,最大值,方差 对比将814条数据按单条插入到哈希MAP和哈希SET: 对比从814条数据的哈希MAP和哈希SET中判断一个元素是否存在(map的hasKey和set的isMember): 大量数据插入哈希MAP,运

Java 线程池 +生产者消费者+MySQL读取300 万条数据

1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解决办法 多线程读取, 生产者 每次获取200 条数据, 消费者去消费.(这里 主要是根据MySQL分页去获取下一个200 条数据) 1.4 代码 1.4.1 调用方法 /** * 线程启动 */ public void update() { //redis操作类 HashRedisUtil redi

SqlServer 创建聚集索引与非聚集索引处理千万条数据的优化,以及之间的区别

在以下的文章中,我将以"办公自动化"系统为例,探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的"红头文件"一表的部分数据结构: CREATE TABLE [dbo].[TGongwen] ( --TGongwen是红头文件表名 [Gid] [int] IDENTITY (1, 1) NOT NULL , --本表的id号,也是主键 [title] [varchar] (80) COLLA

极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量导入的实现有重要意义. .Net程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵.这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Orac

极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方法所耗费的时间. 本实验中所用到工具为VS2008和SQL SERVER 2000.SQL SERVER 2008,分别使用5中方法将100万条数据导入SQL 2000与SQL 2008中,实验环境是DELL 2850双2.0GCPU,2G内存的服务器.感兴趣的朋友可以下载源代码自己验证一下所用时间