Java tps_Java static

Java tps_Java static写在前面TPS即每秒查询事物,可以用于测试一个方法、工具或者系统的性能。本文采用Java并发包中的工具实现了一个工具TPS性能测试。主要是测试OKHttp库来执行Http请求的性能。测试代码用到了Java了线程池ExecuterService,CountDownLatch,CyclicBarrier,原子类,volatile关键词等。可算是对Java并发组件的组合使用。下面直接贴出源码,仅供参考

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

写在前面

TPS即每秒查询事物,可以用于测试一个方法、工具或者系统的性能。本文采用Java并发包中的工具实现了一个工具TPS性能测试。主要是测试OKHttp库来执行Http请求的性能。测试代码用到了Java了线程池ExecuterServiceCountDownLatch, 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并发的常用的工具类。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194201.html原文链接:https://javaforall.net

(0)
上一篇 2025年11月10日 下午3:22
下一篇 2025年11月10日 下午4:01


相关推荐

  • Python中“取整”的各种问题[通俗易懂]

    Python向上取整的算法一、初衷:  有时候我们分页展示数据的时候,需要计算页数。一般都是向上取整,例如counts=205pageCouts=20,pages=11页。一般的除法只是取整数部分,达不到要求。二、方法:1、通用除法:  UP(A/B)=int((A+B-1)/B)  取临界值,计算下A+B-1的范围就OK.2、Python除法:…

    2022年4月17日
    95
  • Spinnaker 核心概念解析

    Spinnaker 核心概念解析Spinnaker 调研汇总参考资料 APIDoc https www spinnaker io reference api docs htmlSwaggerU http 15 114 100 67 8084 swagger ui htmlSpinnake https www spinnaker io reference SpinnakerCod

    2026年3月17日
    2
  • js 数组转json和json转数组

    js 数组转json和json转数组js数组转json和json转数组数组转json串json字符串转数组数组转json串vararr=[1,2,3,{a:1}];JSON.stringify(arr);json字符串转数组varjsonStr='[1,2,3,{“a”:1}]’;JSON.parse(jsonStr);

    2022年6月21日
    30
  • JavaScript 动画效果

    JavaScript 动画效果文章目录 JS 动画实现概述平滑动画无缝连续滚动特效轮播图轮播图淡入淡出效果 JS 动画实现概述在 CSS3 中可以通过 transition 过渡属性可以实现动画 JS 可以利用 CSS3 中的 transition 属性实现元素动画平滑动画利用 CSStransitio 属性实现平滑动画效果 button 开始动画 button divid box script varbtn document queryS script divid box

    2026年3月19日
    3
  • 比 Hadoop 快至少 10 倍的物联网大数据平台,我把它开源了

    比 Hadoop 快至少 10 倍的物联网大数据平台,我把它开源了两天前 7 月 12 号 我对外正式宣布 TDengine 一款专为物联网定制打造的大数据平台软件 正式开源 将我和涛思数据团队两年多的时间写下的 10 多万行 C 语言代码放在 GitH

    2026年3月19日
    4
  • MySQL分库分表原理

    MySQL分库分表原理MySQL 分库分表原理前言数据库为什么要分库分表影响数据库性能的三个要素数据量磁盘数据库连接 1 分库分表的原理和实现 1 1 什么是分区 分表 分库分区分表分库 1 2 什么时候考虑使用分区 分区解决的问题分区的实现方式 简单 例如 1 3 分库分表概述 1 4 适用场景 1 5 业务分库 又叫 mysql 垂直拆分 1 6 业务分表 又叫水平拆分 1 6 1 业务分表带来的问题 1 6 2 路由问题 1 6

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号