多线程处理大数据(再续)

接前篇,前面的程序,是在自己的 mac 上跑的,几十万条数据速度还可以,但是今天用公司的电脑就变慢了。

同样是开启了四条线程处理,但是公司电脑明显不给力。观察了一下CPU,开启四条线程,基本上CPU占用率就跑满了,可能阻塞的时间远大于计算的时间,从而导致变慢。

于是,就写了个单线程的版本,明显快多了,大概不到1秒的样子。

如果是在多核服务器上,数据是百万级别或者更高,多线程的版本应该就体现出优势来了吧。

【注意】 started = true ;一定不要忘记写,不然调用的时候就粗大事儿了。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.CRC32;

public class SingleMobileUtil {
	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 ConcurrentHashMap<String, Location> locationMap = new ConcurrentHashMap<String, Location>();
	private static volatile boolean started = false;
	final SingleMobileUtil mobileUtil = null;
	private static StringBuffer sb = null;

	private SingleMobileUtil() {
	}

	private void initial() {
		timer.scheduleAtFixedRate(new Runnable() {
			public void run() {
				long start = System.nanoTime();
				System.out.println(start);
				InputStreamReader isr;
				BufferedReader br;
				try {
					isr = new InputStreamReader(new FileInputStream(fileName),
							"GBK");
					br = new BufferedReader(isr);

					String str = null;
					sb = new StringBuffer();
					while ((str = br.readLine()) != null) {
						sb.append(str);
						while (true) {
							int j = str.indexOf("\t");
							if (j < 0) {
								break;
							}
							Location lc = new Location();
							String num = str.substring(0,
									str.indexOf("\t")).trim();
							lc.setNum(num);
							str = str.substring(str
									.indexOf("\t") + 1);
							lc.setProvince(str.substring(0,
									str.indexOf("\t")).trim());
							str = str.substring(str
									.indexOf("\t") + 1);
							lc.setCity(str.substring(0,
									str.indexOf("\t")).trim());
							str = str.substring(str
									.indexOf("\t") + 1);
							lc.setOperator(str.trim());
							locationMap.put(num, lc);
						}
					}
					content = sb.toString();
					br.close();
					isr.close();
					started = true;
					System.out.println((System.nanoTime() - start) / 1e9);
					System.out.println(locationMap.size());
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, 0, 1, TimeUnit.MINUTES);
	}

	public static void init() {
		final SingleMobileUtil mobileUtil = new SingleMobileUtil();
		mobileUtil.initial();
	}

	public static void destroy() {
		timer.shutdown();
		content = null;
		locationMap = null;
		started = false;
	}

	public static SingleMobileUtil create() {
		final SingleMobileUtil mobileUtil = new SingleMobileUtil();
		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"));
	}

	private 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、付费专栏及课程。

余额充值