多线程读取大数据文件(续)

昨天的程序有点错误,重新粘一个, for循环终结括号括错了。

另外新加了个destroy()方法

下篇重写了个单线程版本的


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
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.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.CRC32;

public class MobileUtil {
	private static final ScheduledExecutorService timer = Executors
			.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
	private static final String fileName = "d:\\mobilelocation";
	private static long crc32;// 字符串进行crc32数据校验
	private static String content = null;// 获取的内容字符串
	private static HashMap<String, Location> locationMap = new HashMap<String, Location>();
	private static volatile boolean started = false;
	final MobileUtil mobileUtil = null;

	private MobileUtil() {
	}

	private void initial() {
		timer.scheduleWithFixedDelay(new Runnable() {
			public void run() {
				long start = System.nanoTime();
				try {
					//crc32校验
					long crc = crc32(fileName);
					if(crc32 == crc){
						return;
					}
					crc32 = crc;
					System.out.println("开始加载手机号归属地信息...");
					FileInputStream fi = new FileInputStream(fileName);
					InputStreamReader inreader = new InputStreamReader(fi,
							"GBK");
					BufferedReader reader = new BufferedReader(inreader);
					String line = null;
					StringBuilder sb = new StringBuilder();
					int strCount = 0;
					while ((line = reader.readLine()) != null) {
						strCount++;
						sb.append(line + "\r\n");
					}
					content = sb.toString();
					String contentCopy = content;
					int total = contentCopy.length();
					System.out.println(total);
					// 使用的线程数量
					int threadCounts = Runtime.getRuntime()
							.availableProcessors();
					ExecutorService exec = Executors
							.newFixedThreadPool(threadCounts);
					List<Callable<HashMap<String, Location>>> callList = new ArrayList<Callable<HashMap<String, Location>>>();
					int len = strCount / threadCounts;// 平均分割strCount
					// strCount小于线程数
					if (len == 0) {
						threadCounts = strCount;// 采用一个线程处理List中的一个元素
						len = strCount / threadCounts;// 重新平均分割List
					}
					for (int i = 0; i < threadCounts; i++) {
						// 根据线程数量切割字符串为线程数量个子字符串
						final String subContent;
						if (0 == threadCounts - 1) {
							subContent = contentCopy;
						} else {
							int startPos = i * total / threadCounts;
							int endPos = (i + 1) * total / threadCounts;
							if (i != 0)
								while (!contentCopy.substring(startPos - 2,
										startPos).endsWith("\r\n")) {
									startPos++;
								}
							if (i != threadCounts - 1)
								while (!contentCopy.substring(endPos - 2,
										endPos).endsWith("\r\n")) {
									endPos++;
								}
							subContent = contentCopy
									.substring(startPos, endPos);
						}
						callList.add(new Callable<HashMap<String, Location>>() {
							public HashMap<String, Location> call()
									throws Exception {
								String contentCopy = subContent;
								HashMap<String, Location> map = new HashMap<String, Location>();
								while (true) {
									String splitStr = null;
									int j = contentCopy.indexOf("\r\n");
									if (j < 0) {
										break;
									}
									splitStr = contentCopy.substring(0, j);
									Location lc = new Location();
									String num = splitStr.substring(0,
											splitStr.indexOf("\t")).trim();
									lc.setNum(num);
									splitStr = splitStr.substring(splitStr
											.indexOf("\t") + 1);
									lc.setProvince(splitStr.substring(0,
											splitStr.indexOf("\t")).trim());
									splitStr = splitStr.substring(splitStr
											.indexOf("\t") + 1);
									lc.setCity(splitStr.substring(0,
											splitStr.indexOf("\t")).trim());
									splitStr = splitStr.substring(splitStr
											.indexOf("\t") + 1);
									lc.setOperator(splitStr.trim());
									map.put(num, lc);
									contentCopy = contentCopy.substring(j + 1);
								}
								return map;
							}
						});
					}

						List<Future<HashMap<String, Location>>> futureList = exec
								.invokeAll(callList);
						HashMap<String, Location> result = new HashMap<String, Location>();
						for (Future<HashMap<String, Location>> future : futureList) {
							result.putAll(future.get());
						}
						locationMap = result;
						started = true;
						System.out.println("手机号归属地信息加载完毕...用时:"+(System.nanoTime() - start)/1e9+"秒,"+"加载数量:"+strCount);
						exec.shutdown();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
					System.out.println("找不到文件" + fileName + "...");
				} catch (IOException e) {
					e.printStackTrace();
					System.out.println("与文件" + fileName + "通信异常...");

				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}, 0, 30, TimeUnit.MINUTES);
	}

	public static void init() {
		final MobileUtil mobileUtil = new MobileUtil();
		mobileUtil.initial();
	}
	
	public static void destroy(){
		timer.shutdown();
		content = null;
		locationMap = null;
		started = false;
	}
	public static MobileUtil create(){
		final MobileUtil mobileUtil = new MobileUtil();
		while(!started){
			if(started)break;
		}
		return mobileUtil;
	}

	public static void main(String args[]) throws IOException {
		System.out.println(getCity("13811014978"));
		System.out.println(getOperator("13811014978"));
	}

	static class Location {

		private String num;
		private String province;
		private String city;
		private String operator;

		public Location() {
		}

		public String getNum() {
			return num;
		}

		public void setNum(String num) {
			this.num = num;
		}

		public String getProvince() {
			return province;
		}

		public void setProvince(String province) {
			this.province = province;
		}

		public String getCity() {
			return city;
		}

		public void setCity(String city) {
			this.city = city;
		}

		public String getOperator() {
			return operator;
		}

		public void setOperator(String operator) {
			this.operator = operator;
		}
	}

	public static Location getLocation(String mobile) {
		mobile = getNum7(mobile);
		while(!started){
			if(started)break;
		}
		return locationMap.get(mobile);
	}

	public static String getCity(String mobile) {
		while(!started){
			if(started)break;
		}
		mobile = getNum7(mobile);
		System.out.println("mobile:"+mobile);
		if (locationMap.get(mobile) == null)
			return null;
		return locationMap.get(mobile).getCity();
	}

	public static String getProvince(String mobile) {
		mobile = getNum7(mobile);
		while(!started){
			if(started)break;
		}
		if (locationMap.get(mobile) == null)
			return null;
		return locationMap.get(mobile).getProvince();
	}

	public static String getOperator(String mobile) {
		mobile = getNum7(mobile);
		while(!started){
			if(started)break;
		}
		if (locationMap.get(mobile) == null)
			return null;
		return locationMap.get(mobile).getOperator();
	}

	private static String getNum7(String mobile) {
		mobile = mobile.trim();
		if (mobile.length() != 11 || !mobile.startsWith("1")
				|| !mobile.matches("\\d+"))
			throw new IllegalArgumentException("传入的手机号码" + mobile
					+ "不正确,请使用正确的11位数字号码");
		return mobile.substring(0, 7);
	}
	
	private static long crc32(String str){
		CRC32 crc32 = new CRC32();
		byte[] data = str.getBytes();
		for(byte i=0;i<data.length;i++) {
		    data[i] = i;
		}
		crc32.update(data);
		return crc32.getValue();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值