java多线程请求同一接口,模拟高并发

1、多线程工具TreadTestHttp 

package com;

import java.util.concurrent.CountDownLatch;
 
public class TreadTestHttp {
 
    public static void main(String[] args) throws InterruptedException {
        Runnable taskTemp = new Runnable() {
	// 注意,此处是非线程安全的,留坑
            private int iCounter;
 
            @Override
            public void run() {
                for(int i = 0; i < 1; i++) {
                    // 发起请求
                    String r = HttpClientUtil.doGet("http://localhost:9999/fxcrs/test/test");
                    System.out.println("请求结果="+r);
                    iCounter++;
                    System.out.println(System.nanoTime() + " [" + Thread.currentThread().getName() + "] iCounter = " + iCounter);
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        TreadTestHttp latchTest = new TreadTestHttp();
        // 模拟同时开7个线程访问
        latchTest.startTaskAllInOnce(7, taskTemp);
    }
    public long startTaskAllInOnce(int threadNums, final Runnable task) throws InterruptedException {
        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(threadNums);
        for(int i = 0; i < threadNums; i++) {
            Thread t = new Thread() {
                public void run() {
                    try {
                        // 使线程在此等待,当开始门打开时,一起涌入门中
                        startGate.await();
                        try {
                            task.run();
                        } finally {
                            // 将结束门减1,减到0时,就可以开启结束门了
                            endGate.countDown();
                        }
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
            };
            t.start();
        }
        long startTime = System.nanoTime();
        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
        // 因开启门只需一个开关,所以立马就开启开始门
        startGate.countDown();
        // 等等结束门开启
        endGate.await();
        long endTime = System.nanoTime();
        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
        return endTime - startTime;
    }
}

2、get和post请求工具HttpClientUtil

package com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

class HttpClientUtil {
    public static String doGet(String httpurl) {
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpurl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 封装输入流is,并指定字符集
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
            connection.disconnect();// 关闭远程连接
        }
 
        return result;
    }
 
    public static String doPost(String httpUrl, String param) {
 
        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
 
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
            connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(param.getBytes());
            // 通过连接对象获取一个输入流,向远程读取
            if (connection.getResponseCode() == 200) {
 
                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
 
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            connection.disconnect();
        }
        return result;
    }
}

3、实际的运行效果

432371083711700 [Thread[main,5,main]] All thread is ready, concurrent going...
请求结果={"errorText":"同一接口访问上限,请稍后再试","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"bm_code_url_max_count","sEcho":"","iDisplayStart":0}

请求结果={"errorText":"同一接口访问上限,请稍后再试","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"bm_code_url_max_count","sEcho":"","iDisplayStart":0}

请求结果={"errorText":"同一接口访问上限,请稍后再试","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"bm_code_url_max_count","sEcho":"","iDisplayStart":0}

请求结果={"errorText":"同一接口访问上限,请稍后再试","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"bm_code_url_max_count","sEcho":"","iDisplayStart":0}

432371398025100 [Thread-0] iCounter = 3
432371397965500 [Thread-4] iCounter = 2
432371397920900 [Thread-1] iCounter = 1
432371398091600 [Thread-2] iCounter = 4
请求结果={"errorText":"同一接口访问上限,请稍后再试","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"bm_code_url_max_count","sEcho":"","iDisplayStart":0}

432371398524800 [Thread-6] iCounter = 5
请求结果={"errorText":"操作成功","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"success","sEcho":"","iDisplayStart":0}

432371410285100 [Thread-3] iCounter = 6
请求结果={"errorText":"操作成功","iTotalRecords":0,"aaData":"","iTotalDisplayRecords":0,"errorCode":"success","sEcho":"","iDisplayStart":0}

432371410399200 [Thread-5] iCounter = 7
432371411959300 [Thread[main,5,main]] All thread is completed.

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
可以使用Java中的多线程技术来并发请求接口获取数据。一种简单的实现方式是使用Java中的Executor框架来创建线程池,并使用线程池中的线程来执行接口请求任务。 以下是一个简单的示例代码: ```java import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ApiRequester { private static final int THREAD_POOL_SIZE = 10; public static void main(String[] args) { // 创建线程池 ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); // 创建任务列表 List<ApiRequestTask> tasks = new ArrayList<>(); tasks.add(new ApiRequestTask("http://example.com/api1")); tasks.add(new ApiRequestTask("http://example.com/api2")); tasks.add(new ApiRequestTask("http://example.com/api3")); try { // 提交任务并获取Future对象列表 List<Future<String>> futures = executor.invokeAll(tasks); // 处理任务结果 for (Future<String> future : futures) { String result = future.get(); System.out.println(result); } } catch (Exception e) { e.printStackTrace(); } // 关闭线程池 executor.shutdown(); } } class ApiRequestTask implements Callable<String> { private String apiUrl; public ApiRequestTask(String apiUrl) { this.apiUrl = apiUrl; } @Override public String call() throws Exception { // 发送HTTP请求并获取响应 String response = sendHttpRequest(apiUrl); // 处理响应并返回结果 String result = processApiResponse(response); return result; } private String sendHttpRequest(String apiUrl) { // 发送HTTP请求并获取响应 // ... return "API response"; } private String processApiResponse(String response) { // 处理API响应并返回结果 // ... return "Processed API response"; } } ``` 在上面的示例代码中,我们首先创建了一个固定大小的线程池,并将其用于执行接口请求任务。然后,我们创建了一个任务列表,其中包含了需要请求接口地址。接下来,我们使用Executor框架的invokeAll方法将任务列表提交给线程池,并获取了一个Future对象列表。最后,我们遍历Future对象列表,获取任务结果并进行处理。 注意,在实际的应用中,需要根据具体的需求来选择合适的线程池大小和任务列表。同时,需要注意避免过度并发导致接口请求过于频繁,可能会给接口服务器带来过大的负担。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

renkai721

谢谢您的打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值