当前位置: 首页 > 面试题库 >

如何在多线程环境中有效使用RestTemplate?

卜高超
2023-03-14
问题内容

我正在开发一个项目,在该项目中,我需要对正在运行的服务器进行HTTP URL调用,该服务器Restful Service将响应作为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接口并使用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它调用的getData方法TimeoutThreadExample5000 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
        }
    }
}

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

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

通常,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;
    }
}

问题答案:

如果我不明白您的问题,请纠正我。它似乎与这里的前一个非常相似。

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

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

我将创建RestTemplatein TimeoutThreadExample并将其Task作为构造函数参数传递给the 。

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创建其连接。



 类似资料:
  • 我正在做一个项目,在这个项目中,我需要对运行

  • 我正在使用多线程执行插入操作。我使用了带注释的方法,我的方法是注释。但我无法执行插入操作,导致出现以下异常。 异常线程"Thread-21"javax.persistence.Transaction必需异常:在org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)在sun.reflect.Native

  • 问题内容: 典型的(对于x86-64平台和Linux OS)是在开始时幼稚地锁定互斥锁并在完成后将其释放,还是以更巧妙的方式将互斥锁锁定在更精细的级别,从而减少了锁争用?如果确实采用第二种方法,那么该如何做? 问题答案: 经营多个分配 场所 。每个竞技场都有自己的锁。当线程需要分配内存时,选择一个竞技场,将其锁定,然后从中分配内存。 选择竞技场的机制有些复杂,旨在减少锁争用: 考虑到这一点,基本上

  • 关于Spring WebClient我有一个问题 在我的应用程序中,我需要做许多类似的API调用,有时我需要更改调用中的头(身份验证令牌)。所以问题来了,在这两个选择中,什么更好: > 为所有传入的MyService.class请求创建一个WebClient,方法是将其设置为字段,如下代码所示: 谢谢你。

  • 我正在使用作为我的一个库中的。我不确定我是否在多线程环境中正确地使用它,因为我的库在多线程环境中会在非常大的负载下使用,所以它必须非常快。 下面是我的DataClient类: 这就是我要打电话获取数据的方式: 现在我的问题是--我不确定我是否正确地将与一起使用。这里是否需要以及? 我的主要目标是在多线程环境中高效地使用。因为我的库将在非常大的负荷下使用,所以它必须非常快。在重载下,我看到了大量的T

  • 问题内容: 一段时间以来,我一直在多线程环境中使用HttpClient。对于每个线程,当它启动连接时,它将创建一个全新的HttpClient实例。 最近,我发现使用这种方法可能导致用户打开太多端口,并且大多数连接处于TIME_WAIT状态。 http://www.opensubscriber.com/message/commons-httpclient- dev@jakarta.apache.or