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

以下是我使用futurecallables的主要代码-

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接口(interface)并使用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中具有以下代码,该类依次调用getDataTimeoutThreadExample中的5000 times方法-
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
        }
    }
}

所以我的问题是,在我的RestTemplateTask class是否应该是静态的,就像我正确看到的一样,我正在为RestTemplate中的每个请求重新创建整个连接池,这不是我想的正确方法。

注意:如果我将RestTemplate设为静态,则在注释掉可衡量性能的RestTemplate类中的line1和line2之后,与非静态DemoTest相比,我看到了更好的端到端性能。

通常,在多线程环境中使用RestTemplate的正确方法是什么?当前,我依次调用getData方法5000次,但有些客户会以多线程方式调用它,因此需要了解在多线程环境中使用RestTemplate的最佳方法是什么。

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

更新:-
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;
    }
}

最佳答案

如果我不明白您的问题,请纠正我。似乎与上一个here非常相似。

在那里,我们确定RestTemplate是线程安全的。因此,没有理由不在有意义的地方共享它。无论您在哪里以相同的方式使用它。
您的示例似乎是执行此操作的理想场所。

如您所述,为每个RestTemplate实例重新创建一个Task实例是浪费的。

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

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对象之间共享Task实例。

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

关于java - 如何在多线程环境中有效使用RestTemplate?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21242812/

10-12 03:40