Java TPS实现
2016-07-09 18:19
1256 查看
写在前面
TPS即每秒查询事物,可以用于测试一个方法、工具或者系统的性能。本文采用Java并发包中的工具实现了一个工具TPS性能测试。主要是测试OKHttp库来执行Http请求的性能。测试代码用到了Java了线程池ExecuterService,
CountDownLatch,
CyclicBarrier, 原子类,
volatile关键词等。可算是对Java并发组件的组合使用。下面直接贴出源码,仅供参考,如有错误,欢迎指出,以期共同探讨。
TPS 实现源码
package cn.concurrent; import java.math.RoundingMode; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import util.OkHttpUtil; import com.google.common.math.LongMath; /** * 每秒事物执行次数统计 * * @author Xie le * @date 2016/7/9 */ public class TpsWorkbeanch { /** 线程数量 */ public static final int N_THRESHOLDS = 5; /** 30 秒总时间 */ public static final int TIME_THRESHOLDS = 30; /** 用原子变量来统计执行时间,便于作原子递减 */ private static AtomicInteger totalTime = new AtomicInteger(TIME_THRESHOLDS); /** 用于统计执行的事物总数,用原子方式累加记录 */ private static AtomicLong totalExecCount = new AtomicLong(0L); /** 需要到等到所有线程都在同一起跑线,才开始统计计数,类似于发令枪 */ private static CyclicBarrier barrier = new CyclicBarrier(N_THRESHOLDS); /** 执行时间到达时,所有的线程需要依次退出,主线程才开始统计执行事物总数 */ private static CountDownLatch countDownLatch = new CountDownLatch(N_THRESHOLDS); /** 线程执行标记 , 用volatile修饰,使变量修改具有线程可见性 */ private static volatile boolean runnning = true; /** 用线程池来执行统计 */ private static ExecutorService executorService; /** * 用接口来作模拟统计 */ interface Job { void execute() throws Exception; } /** * 具体Job,模拟完成一次Http请求 BTW:内部类用static修饰 */ static class JobDetail implements Job { public void execute() throws Exception { String run = OkHttpUtil.run("http://publicobject.com/helloworld.txt"); } } /** * Worker执行Job */ static class Worker implements Runnable { private Job job; Worker(Job job) { this.job = job; } // 每个线程执行的事物统计量 int innerCount = 0; public void run() { try { barrier.await(); // 等到所有线程都在起跑线 while (runnning) { this.job.execute(); innerCount++; } } catch (Exception e) { System.out.println("线程Id:" + Thread.currentThread().getId() + " " + e.getMessage()); } finally { // 累加到总记录统计量 System.out.println("线程Id:" + Thread.currentThread().getId() + " 执行事物次数为:" + innerCount); totalExecCount.getAndAdd(innerCount); // 线程结束后,依次计数, 便于主线程继续执行 countDownLatch.countDown(); } } } public static void run() throws Exception { Job job = new JobDetail(); // 创建Job executorService = Executors.newFixedThreadPool(N_THRESHOLDS); // 新建固定大小线程的池子 for (int i = 0; i < N_THRESHOLDS; i++) { executorService.submit(new Worker(job)); // 提交线程到池子中 } // 还需要一个线程,用于周期检查执行时间是否到达 final ScheduledExecutorService scheduledExcutor = Executors.newSingleThreadScheduledExecutor(); scheduledExcutor.scheduleAtFixedRate(new Runnable() { public void run() { if (totalTime.decrementAndGet() == 0) { // 执行时间递减到0 runnning = false; // 告诉线程,时间到了,所有线程不再执行 scheduledExcutor.shutdownNow(); } } }, 1L, 1L, TimeUnit.SECONDS); // 主线程等到所有的线程都退出,则开始统计 countDownLatch.await(); long totalExeCount = totalExecCount.get(); System.out.println(N_THRESHOLDS + " 个线程," + TIME_THRESHOLDS + " 秒内总共执行的事物数量:" + totalExeCount); long tps = LongMath.divide(totalExeCount, TIME_THRESHOLDS, RoundingMode.HALF_EVEN); System.out.println("OKHttp执行的TPS: " + tps); executorService.shutdownNow(); // 关闭线程池 } public static void main(String[] args) throws Exception { run(); } }
其中用到的OKHttp类如下:
package util; import java.io.IOException; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** * OkHttp工具 * @author Xie le * @date 2016/6/30 */ public class OkHttpUtil { private static OkHttpClient okHttpclient = null; static { okHttpclient = new OkHttpClient.Builder() .connectTimeout(3, TimeUnit.SECONDS) .build(); } public static String run(String url) throws Exception { Request request = new Request.Builder().url(url).build(); Response response = okHttpclient.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } return response.body().string(); } }
测试结果
测试结果与环境有关。以我本机为例,5个线程,30秒内的测试结果如下:线程Id:14 connect timed out 线程Id:14 执行事物次数为:0 线程Id:10 connect timed out 线程Id:10 执行事物次数为:0 线程Id:11 执行事物次数为:29 线程Id:13 执行事物次数为:33 线程Id:12 执行事物次数为:26 5 个线程,30 秒内总共执行的事物数量:88 OKHttp执行的TPS: 3
最后
直接阅读代码,可以掌握Java并发的常用的工具类。相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树