前言:
当前同学们对“java多线程测试方法”可能比较关切,咱们都需要剖析一些“java多线程测试方法”的相关内容。那么小编同时在网络上搜集了一些关于“java多线程测试方法””的相关知识,希望我们能喜欢,你们快快来学习一下吧!一、摘要
很多时候,新开发的功能在上线之前,我们都会进行压力测试,以防上线之后,突然出现性能瓶颈或者出现线程安全问题。
那么问题来了,如何进行压力测试呢?
实践的手段有很多种,比如采用 jmeter 、fiddler、postman 等第三方工具,可以快速实现性能压力测试。
当然除此之外,其实我们也利用 java 的多线程特性,完全可以自行编写一套多线程的压力测试。
下面我们以访问百度首页服务为例,向大家演示一下,采用 java 的多线程特性,该如何编写并发测试。
二、代码实践2.1、方案一
说到多线程,大家可能想到的就是实例化一个Thread对象,然后启动它,就可以实现异步处理,以模拟100个用户同时请求百度首页为例,代码实践如下:
public static void main(String[] args) throws InterruptedException { //模拟100个线程,同时请求百度首页 long start = System.currentTimeMillis(); final int threadNum = 100; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; new Thread(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); //访问百度首页 String url = ";; String rs = HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + rs); System.out.println("thread " + threadCount + " final"); //执行完成之后,计数器减一 countDownLatch.countDown(); } }).start(); } //线程同步阻塞 countDownLatch.await(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms");}
实践过程非常简单,采用Thread + CountDownLatch组合,进行阻塞测试。
但是实际上往往我们进行多线程模拟用户进行访问某个服务的时候,每个用户的请求参数是不一样的,这个时候我们应该如何更加真实的贴近用户实际请求去测试呢?请看下面这个方案!
2.1、方案二
实际上在多线程并发编程中,它还有一个完美搭档,那就是队列,采用多线程+队列组合编程模型,可以实现带任务的异步处理,并且性能高效!
下面我们还是以访问百度首页服务为例,采用多线程+队列组合模式来模拟 100 个用户总共发起了1000次访问百度首页,代码实践如下!
public static void main(String[] args) throws InterruptedException { //将每个用户访问百度服务的请求参数,存入阻塞队列BlockingQueue中 BlockingQueue<String> queue = new LinkedBlockingQueue<>(); for (int i = 0; i < 1000; i++) { queue.put("; + i); } //模拟100个线程,执行1000次请求访问百度 long start = System.currentTimeMillis(); final int threadNum = 100; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; new Thread(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); boolean over = false; while (!over) { String url = queue.poll(); if(Objects.nonNull(url)) { //发起请求 String result =HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + result); }else { //任务结束 over = true; System.out.println("thread " + threadCount + " final"); countDownLatch.countDown(); } } } }).start(); } countDownLatch.await(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms");}
当然,你还可以自由调整线程数,也可以采用juc包的线程池来实现多线程编程,改造逻辑如下:
public static void main(String[] args) throws InterruptedException { //将每个用户访问百度服务的请求参数,存入阻塞队列BlockingQueue中 BlockingQueue<String> queue = new LinkedBlockingQueue<>(); for (int i = 0; i < 1000; i++) { queue.put("; + i); } //模拟100个线程,执行1000次请求访问百度 long start = System.currentTimeMillis(); final int threadNum = 100; //线程计数器 final CountDownLatch countDownLatch = new CountDownLatch(threadNum); //执行线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; fixedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); boolean over = false; while (!over) { String url = queue.poll(); if(Objects.nonNull(url)) { //发起请求 String result =HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + result); }else { //任务结束 over = true; System.out.println("thread " + threadCount + " final"); countDownLatch.countDown(); } } } }); } countDownLatch.await(); fixedThreadPool.shutdown(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms");}
其中BlockingQueue阻塞队列,支持线程数据共享,当一个线程把数据取出之后,另一个线程无法再取,最后的运行效果是一样的!
三、小结
本文主要围绕采用多线程编程,实现服务性能压力测试进行案例介绍,如果有描述不对的地方,欢迎网友批评指出!
标签: #java多线程测试方法