本文介绍了如何在多线程环境中高效使用 RestTemplate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个项目,在该项目中我需要对运行 Restful Service 的服务器进行 HTTP URL 调用,该服务器将响应作为 JSON 字符串返回.

I am working on a project in which I need to make a HTTP URL call to my server which is running Restful Service which returns back the response as a JSON String.

下面是我的主要代码,它使用了 futurecallables -

Below is my main code which is using the future and callables -

public class TimeoutThreadExample {

    private ExecutorService executor = Executors.newFixedThreadPool(10);

    public String getData() {
        Future<String> future = executor.submit(new Task());
        String response = null;

        try {
            response = future.get(100, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return response;
    }
}

下面是我的 Task 类,它实现了 Callable 接口并使用了 RestTemplate...

Below is my Task class which implements the Callable interface and uses the RestTemplate...

class Task implements Callable<String> {

    private RestTemplate restTemplate = new RestTemplate();

    public String call() throws Exception {

        String url = "some_url";
        String response = restTemplate.getForObject(url, String.class);

        return response;
    }
}

现在我在另一个类 DemoTest 中有以下代码,它调用 TimeoutThreadExample 类中的 getData 方法 5000 次 按顺序 -

And now I have below code in another class DemoTest which calls the getData method in TimeoutThreadExample class 5000 times sequentially -

public class DemoTest { 
   public static void main(String[] args) {

        TimeoutThreadExample bc = new TimeoutThreadExample();

        for (int i = 0; i <= 5000; i++) {
        //  TimerTest timer = TimerTest.getInstance(); // line 1
            bc.getData();
        //  timer.getDuration(); // line 2
        }
    }
}       

所以我的问题是 RestTemplate 在我的 Task class 中应该是静态的,就好像我没看错一样,我正在为 中的每个请求重新创建整个连接池>RestTemplate 我猜这不是正确的方法..

So my question is should RestTemplate be static here in my Task class as if I see it correctly, I am recreating the whole connection pool for each request in RestTemplate which is not the right way I guess..

注意:如果我将 RestTemplate 设为静态,那么在注释掉 中的 line1 和 line2 后,与非静态 RestTemplate 相比,我看到端到端的性能更好DemoTest 类,用于衡量性能.

NOTE: If I am making RestTemplate static, then I see better performance end to end as compared to non static RestTemplate after commenting out line1 and line2 in DemoTest class which measures the performance.

一般来说,在多线程环境中使用 RestTemplate 的正确方法是什么?目前,我正在依次调用 getData 方法 5000 次,但有些客户会以多线程方式调用它,因此需要知道在多线程环境中使用 RestTemplate 的最佳方法是什么..

In general what is the right way to use RestTemplate in Multithreading environment? Currently I am calling sequentially getData method 5000 times one by one but some customer will call it in a multithreaded way so need to know what is the best way to have RestTemplate in a multithreaded environment..

可能是在 RestTemplate 构造函数中使用 ConnectionFactory 吗?有什么想法吗?

May be to use ConnectionFactory in the RestTemplate constructor? Any thoughts?

更新:-

public class TimeoutThreadExample {

    private ExecutorService executor = Executors.newFixedThreadPool(10);
    private RestTemplate restTemplate = new RestTemplate();

    public String getData() {
        Future<String> future = executor.submit(new Task(restTemplate));
        String response = null;

        try {
            response = future.get(100, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return response;
    }
}

在我的 TaskClass 下方 -

class Task implements Callable<String> {

    private RestTemplate restTemplate;

    public Task(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String call() throws Exception {

        String url = "some_url";
        String response = restTemplate.getForObject(url, String.class);

        return response;
    }
}

推荐答案

如果我不明白你的问题,请纠正我.它看起来与此处的前一个非常相似.

Correct me if I didn't understand your question. It seems very similar to the previous one here.

在那里,我们确定 RestTemplate 是线程安全的.因此,没有理由不在任何有意义的地方共享它,即.无论您在哪里都以相同的方式使用它.您的示例似乎是这样做的理想场所.

There, we determined that RestTemplate is thread-safe. There is therefore no reason not to share it wherever it makes sense to, ie. wherever you are using it in the same way. Your example seems like the perfect place to do so.

正如您所说,为每个 Task 实例重新创建一个 RestTemplate 的新实例是一种浪费.

As you stated, recreating a new instance of RestTemplate for each Task instance is wasteful.

我将在 TimeoutThreadExample 中创建 RestTemplate 并将其作为构造函数参数传递给 Task.

I would create the RestTemplate in TimeoutThreadExample and pass it to the Task as a constructor argument.

class Task implements Callable<String> {

    private RestTemplate restTemplate;

    public Task(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String call() throws Exception {

        String url = "some_url";
        String response = restTemplate.getForObject(url, String.class);

        return response;
    }
}

通过这种方式,您可以在所有 Task 对象之间共享 RestTemplate 实例.

This way you share the RestTemplate instance between all your Task objects.

请注意,RestTemplate 使用 SimpleClientHttpRequestFactory 来创建其连接.

Note that RestTemplate uses SimpleClientHttpRequestFactory to create its connections.

这篇关于如何在多线程环境中高效使用 RestTemplate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-20 02:30