您的位置:首页 > 其它

【多线程 4】多线程实例(实例分析博客在下一篇)

2016-10-26 20:20 211 查看

一、概述

额,这篇博客有点水哈,就是自己拿到一个需求之后,写的模拟场景代码。不是很完善,纯属自己的一个代码记录。先描述一下需求:

现在存在着N个点(注意:N个代码大批量数据),这N个点(对象Point)存放在一个动态数组里。每个点包含有X和Y属性!当这些点与已知点的距离,不小于D时,为正常数据,反之,则为异常数据,需要将这些数据剔除!

二、分析

1,首先建立一个point对象,包含X和Y属性

2,编写计算两点之间距离的方法

3,编写一个方法,模拟大批量数据(嘿嘿,这里就模拟了50个,见笑了)

4,编写一个方法,找出异常数据

5,编写主程序,得出最终符合条件的结果

三、代码

3.1,Point的代码就省略了,private double x; private doubley; 然后,创建各自的get 和set 方法

3.2,distance()计算两点间的距离

<span style="font-family:KaiTi_GB2312;font-size:18px;">	/**
* 计算两点之间的距离
*
* @param basePoint 原点,对比点
* @param current 当前获取的点
* @return 两点间的距离
*/
public static double distance(Point basePoint, Point current) {// 求两点的距离
return (double) Math.sqrt((current.getX() - basePoint.getX())
* (current.getX() - basePoint.getX())
+ (current.getY() - basePoint.getY())
* (current.getY() - basePoint.getY()));
}</span>


3.3,init()模拟数据

<span style="font-family:KaiTi_GB2312;font-size:18px;">/**
* 初始化已知条件,待查找数量为50个
*/
public static List<Point> init() {
// 第一题,声明一个动态数组
List<Point> ary = new ArrayList<Point>();

// 赋值ary数组,假设有50个
for (int i = 0; i < 50; i++) {
// 利用随机生成函数,生成X和Y
Random rand = new Random();
double x = rand.nextDouble() * 10.0 + 0;
double y = rand.nextDouble() * 10.0 + 0;
Point MyPoint = new Point();
MyPoint.setX(x);
MyPoint.setY(y);
ary.add(MyPoint);

}
return ary;
}</span>


3.4,findTheEle()找出异常数据

<span style="font-family:KaiTi_GB2312;font-size:18px;">	/**
* 找出小于d的数据
*/
@SuppressWarnings("finally")
public static List<Point> findTheEle(List<Point> ary, Point basePoint,
double d) {
// 启用线程的数量
int ThreadNum = ary.size() / 11;
// 接收结果的list
List<Point> listResult = new ArrayList<Point>();

Future<String> future = null;

// 如果任务没有平均分配完,则增加一个线程
int remainTask = ary.size() % 11;
if (remainTask > 0) {
ThreadNum += 1;
}

// 启动ThreadNum个定长线程,同时计算
ExecutorService threadPool = Executors.newFixedThreadPool(ThreadNum);

for (int i = 0; i < ThreadNum; i++) {
int threadNum = i;
// 使用submit方法,捕获线程执行结果(execute没有返回结果)
future = threadPool.submit(new Callable<String>() {
public String call() {
for (int j = threadNum * 11; j < 11 + 11 * threadNum; j++) {
Point current = ary.get(j);
double distance = distance(basePoint, current);
if (distance < d) {
listResult.add(current);
}
System.out.println(Thread.currentThread().getName()
+ "正在计算第" + j + "个点!" + "当前为第" + threadNum+ "个任务!");
if (j == ary.size() - 1) {
break;
}
}
return "success";
}
});

}

try {
//如果线程池里还有正在执行计算的线程
if (threadPool.isTerminated() == false) {
boolean isCompletion = false;
do {
try {
// 阻塞主线程,直到线程池里所有任务结束
isCompletion = !threadPool.awaitTermination(2,TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (isCompletion == false);
}
System.out.println("查找距离小于d的任务结果:" + future.get());
System.out.println("不符合的点共有:" + listResult.size() + "个");

} catch (InterruptedException | ExecutionException e) {
System.out.println(e.getCause().getMessage());
} finally {
threadPool.shutdown();
}
return listResult;
}</span>


3.5,主程序

<span style="font-family:KaiTi_GB2312;font-size:18px;">	// 主程序,从大批量数据中,查找符合条件的部分
public static void main(String[] arg) {

Point basePoint = new Point();// 假设currpoint当前点为原点;
basePoint.setX(0);
basePoint.setY(0);
double d = 5;
List<Point> list = new ArrayList<Point>();
list = init();
System.out.println("原始数据共有:" + list.size());
List<Point> theWrongData = findTheEle(list, basePoint, d);

// 剔除脏数据之后的结果
list.removeAll(theWrongData);
System.out.println("符合条件的数据共有:" + list.size());

}</span>


四、总结

当时拿到这个需求的时候,想到了优化方案就是分割list,然后启用多线程同时计算。额,有点瑕疵,但是也算是任务完成。下篇博客再来介绍这里面的问题,比如说,线程池有哪几种类型,各自的应用场景是什么?同时启动了几个线程,万一线程死了,或者执行任务失败了怎么办?为什么用了submit方法而不是execute方法?为什么使用了阻塞线程?还有就是,list数据结构大批量数据的处理问题,以及多线程任务调度的问题?

因为在这里考虑过用消息队列的形式处理大批量数据,额,没用上,接下来再用!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: