接前篇,前面的程序,是在自己的 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();
}
}