六大质量属性以——以“信息领域热词分析系统”为例性能代码分析
性能战术的目标:对一定时间限制内到达系统的事件生成一个响应,这些事件可以是消息到达、定时器到时,系统状态的变化。
性能战术的分类以及基本的方法
资源需求:
需求具有两个特性:资源流中事件之间的时间间隔;每个请求所消耗的资源
1.减少一个事件流所用的资源
(1)提高计算效率,如改进关键算法
比如在数据查找时采用二分查找法可以大大减少查找时间
(2)减少计算开销
比如保留上次计算结果
2.减少处理事件的数量,减小频率。
(1)管理事件率
(2)控制采样频率
3.控制资源的使用
(1)限制执行时间
(2)限制队列大小
结合以上总结,首先我认为可以改进自我代码的算法如:
二分查找法:
public int getPos(int[] A, int n, int val) { // write code here if (n <= 0) {//如果数组长度为0 return -1; } if (n == 1) {//如果数组长度为1 if (A[0] == val) { return 0; }else { return -1; } } int left = 0;//左侧索引 int right = n-1;//右侧索引 int mid = 0; while (left <= right) {//注意这里是小于等于 mid = left + (right-left)/2;//取中间的值 if (val == A[mid]) {//如果相等,则返回索引位置 return mid; }else if (val > A[mid]){ //如果大于,则选择右边半部分继续比较 left = mid+1; }else{//如果小于,则选择左边半部分继续比较 right = mid-1; } } return -1; }
或者减少事件数量、减少频率或者限制队列大小或者限制时间
限制队列大小我个人觉得应该处理在于数据库方面,比如我只差某个时间段的热词,只对该时间段进行分析,数量就可大大减少,那么就可以根据时间进行数据排查筛选分析
或者也可以限制时间
比如
public static void main(String[] args) throws InterruptedException, ExecutionException { final ExecutorService exec = Executors.newFixedThreadPool(1); Callable<String> call = new Callable<String>() { public String call() throws Exception { //开始执行耗时操作 Thread.sleep(1000 * 5); return "线程执行完成."; } }; try { Future<String> future = exec.submit(call); String obj = future.get(1000 * 2, TimeUnit.MILLISECONDS); //任务处理超时时间设为 2 秒 System.out.println("任务成功返回:" + obj); } catch (TimeoutException ex) { ex.printStackTrace(); } catch (Exception e) { System.out.println("处理失败."); e.printStackTrace(); } // 关闭线程池 exec.shutdown();
限制队列大小
比如Queue
Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构
Queue的实现
1、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口
2.实现阻塞接口的:
java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。
例如
public static class Basket{ // 篮子,能够容纳3个苹果 BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3); // 生产苹果,放入篮子 public void produce() throws InterruptedException{ // put方法放入一个苹果,若basket满了,等到basket有位置 basket.put("An apple"); } // 消费苹果,从篮子中取走 public String consume() throws InterruptedException{ // get方法取出一个苹果,若basket为空,等到basket有苹果为止 String apple = basket.take(); return apple; } public int getAppleNumber(){ return basket.size(); } } // 测试方法 public static void testBasket() { // 建立一个装苹果的篮子 final Basket basket = new Basket(); // 定义苹果生产者 class Producer implements Runnable { public void run() { try { while (true) { // 生产苹果 System.out.println("生产者准备生产苹果:" + System.currentTimeMillis()); basket.produce(); System.out.println("生产者生产苹果完毕:" + System.currentTimeMillis()); System.out.println("生产完后有苹果:"+basket.getAppleNumber()+"个"); // 休眠300ms Thread.sleep(300); } } catch (InterruptedException ex) { } } } // 定义苹果消费者 class Consumer implements Runnable { public void run() { try { while (true) { // 消费苹果 System.out.println("消费者准备消费苹果:" + System.currentTimeMillis()); basket.consume(); System.out.println("消费者消费苹果完毕:" + System.currentTimeMillis()); System.out.println("消费完后有苹果:"+basket.getAppleNumber()+"个"); // 休眠1000ms Thread.sleep(1000); } } catch (InterruptedException ex) { } } } ExecutorService service = Executors.newCachedThreadPool(); Producer producer = new Producer(); Consumer consumer = new Consumer(); service.submit(producer); service.submit(consumer); // 程序运行10s后,所有任务停止 try { Thread.sleep(10000); } catch (InterruptedException e) { } service.shutdownNow(); } public static void main(String[] args) { BlockingQueueTest.testBasket(); }
资源管理:
1.引入并发
2.维持数据或计算的多个副本
3.增加可用资源
这个受硬件影响较大
资源仲裁
当程序对资源争用的时候,进行相关的资源调度,以使资源协调一致的运行,以减少闭锁时间。
1.先进先出,同等看待每个资源
2.固定优先级,事先为某个事件分配优先级
3.动态优先级,运行时分配优先级
4.静态调度,非运行时确定资源的分配顺序
package com.first; public class ThreadPriority { public static void main(String[] args) { System.out.println(Thread.currentThread().getName() +"("+Thread.currentThread().getPriority()+ ")"); Thread t1=new ThreadP("thread1"); // 新建t1 Thread t2=new ThreadP("thread2"); // 新建t2 t1.setPriority(5); // 设置t1的优先级为1 t2.setPriority(5); // 设置t2的优先级为10 t1.start(); // 启动t1 t2.start(); // 启动t2 } } class ThreadP extends Thread{ public ThreadP(String name) { super(name); } public void run(){ for (int i=0; i<5; i++) { System.out.println(Thread.currentThread().getName() +"("+Thread.currentThread().getPriority()+ ")" +", loop "+i); } } }
参考:Java队列————quene详细分析https://www.cnblogs.com/lemon-flm/p/7877898.html