如何在多线程环境中有效地使用RestTemplate? [英] How to use RestTemplate efficiently in Multithreaded environment?

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

问题描述

我正在开发一个项目,我需要对我的服务器进行HTTP URL调用,该服务器运行 Restful Service ,它将响应作为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.

以下是我使用 future callables -

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;
    }
}

以下是我的任务实现 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 class <$ c $中调用 getData 方法c> 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 在我的任务类中是静态的,就像我正确看到它一样,我正在重新创建整个连接 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.

如您所述,重新创建 RestTemplate的新实例每个任务实例都很浪费。

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

我会创建 RestTemplate TimeoutThreadExample 中,并将其作为构造函数参数传递给任务

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;
    }
}

这样你就可以分享所有任务对象之间的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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆