zoukankan      html  css  js  c++  java
  • 【多线程 4】多线程实例(实例分析博客在下一篇)

    一、概述

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

    现在存在着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数据结构大批量数据的处理问题,以及多线程任务调度的问题?

    因为在这里考虑过用消息队列的形式处理大批量数据,额,没用上,接下来再用!

  • 相关阅读:
    移植BOA
    [转]Ubuntu(Linux)使用Eclipse搭建C/C++编译环境
    服务器软件设计的算法和问题
    [solve]Bind: Address Already in Use
    Simple guide for Automake/Autoconf by Nick
    Ubuntu(Linux)中设置samba
    VMware不能上网,解决办法
    数组的顺序存储和实现
    根文件系统的构成
    Linux网络编程IP转换函数inet_addr和inet_ntoa
  • 原文地址:https://www.cnblogs.com/hhx626/p/7534630.html
Copyright © 2011-2022 走看看