当前位置: 首页 > 知识库问答 >
问题:

Java Spring-管理同步请求的线程

文彭祖
2023-03-14

我有一个Java web应用程序,使用SPRING进行REST调用。

我想控制应用程序为请求打开的线程数。

所以我添加了线程配置:

package myPackage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
public class ThreadConfig {
    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.initialize();
        return executor;
    }
}

我使用的同步服务不是异步的,我对它进行了测试,它没有限制处理请求的线程,而是同时处理所有请求。

我所期望的是,当我一次发送两个请求时,要么抛出第二个请求,要么等待第一个请求完成。

我根本没有在我的应用程序中实现Thread。这是我的控制器的相关代码:

    @RestController
    public class Module1Controller {
        @RequestMapping(method = RequestMethod.GET, path = "/module1")
InterruptedException {
        public Module1 Module1() throws InterruptedException {
            Date startDate = new Date();
            System.out.println("Thread #: " + Thread.currentThread().getId() + " Request received at: " + startDate);
            Thread.sleep(10000);
            Date endDate = new Date();
            long diff = endDate.getTime() - startDate.getTime();
            long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
            System.out.println("Thread #: " + Thread.currentThread().getId() + " thread released at: " + endDate + ", total seconds: " + seconds);
            return new Module1(new Clock());
        }

这是控制台结果:

Thread #: 34 Request received at: Sun Dec 17 10:16:20 IST 2017
Thread #: 35 Request received at: Sun Dec 17 10:16:21 IST 2017
Thread #: 34 thread released at: Sun Dec 17 10:16:30 IST 2017, total seconds: 10
Thread #: 35 thread released at: Sun Dec 17 10:16:31 IST 2017, total seconds: 10

我错过了什么?

共有2个答案

庞意智
2023-03-14

您不能在容器中控制应用程序中的请求线程。也许您想在应用程序中的有限线程中运行一些任务。您可以这样做:

@RestController
public class ThreadController {
@Autowired
private TaskExecutor taskExecutor;

@RequestMapping(method = RequestMethod.GET, path = "/thread")
public void Module1() {


    taskExecutor.execute(new Runnable() {
        @Override
        public void run() {
            Date startDate = new Date();
            System.out.println("Thread #: " + Thread.currentThread().getId() +
                    " Request received at: " + startDate);
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Date endDate = new Date();
            long diff = endDate.getTime() - startDate.getTime();
            long seconds = TimeUnit.MILLISECONDS.toSeconds(diff);
            System.out.println("Thread #: " + Thread.currentThread().getId() +
                    " thread released at: " + endDate + ", total seconds: " + seconds);
        }
    });
  }
}

结果:

Thread #: 55 Request received at: Sun Dec 17 22:40:57 CST 2017
Thread #: 55 thread released at: Sun Dec 17 22:41:07 CST 2017, total seconds: 10
Thread #: 55 Request received at: Sun Dec 17 22:41:16 CST 2017
Thread #: 55 thread released at: Sun Dec 17 22:41:26 CST 2017, total seconds: 10
Thread #: 55 Request received at: Sun Dec 17 22:41:32 CST 2017
Thread #: 55 thread released at: Sun Dec 17 22:41:42 CST 2017, total seconds: 10
云令
2023-03-14

问题是在配置bean中创建TaskExecutor对RestController没有影响。

使RestController一次只处理1个请求的最简单方法是使处理方法同步,例如:

@RequestMapping(method = RequestMethod.GET, path = "/module1")
public synchronized Module1 getModule1() throws InterruptedException {

如果您希望同时处理某个最大数量的请求,您可以使用FixedThreadPool,例如:

// allow only 2 requests at a time, more requests are automatically placed in a queue
private final ExecutorService es = Executors.newFixedThreadPool(2);

@RequestMapping(method = RequestMethod.GET, path = "/module1")
public Module1 getModule1() throws ExecutionException, InterruptedException {
    Future<Module1> result = es.submit(new Callable<Module1>() {
        @Override
        public String call() throws Exception {
            try {
                //.... do your work here....
                return Module1()
            } catch (InterruptedException e) {
                return null;
            }
        }
    });
    return result.get();
}

我不知道你为什么要这样做。限制请求数量将导致性能不佳,用户不会喜欢这样。

 类似资料:
  • 我如何用RxJava方法实现上面的场景?我希望利用某种现有的运算符,以声明性更强的方式组合它们,最重要的是,避免同步、锁和原子的开销。

  • 问题内容: 如果我需要按顺序调用3 http API,那么以下代码将是更好的选择: 问题答案: 使用像这样的延期。 如果您需要传递范围,则只需执行以下操作

  • 问题内容: 同步请求和异步请求之间的性能(速度方面)是否有差异? 使用异步请求的所有原因是什么? 问题答案: 您应该始终使用异步Ajax请求,实际上,我只知道应该使用同步Ajax请求的一个地方,即您是否在Ajax请求中,将新的JavaScript文件嵌入客户端,然后引用类型和/或原始Ajax请求返回的JavaScript文件中的对象。然后,应该(或可以理智地)通过使用同步Ajax请求包括对这个新J

  • Spring MVC 3.2开始引入了基于Servlet 3的异步请求处理。相比以前,控制器方法已经不一定需要返回一个值,而是可以返回一个java.util.concurrent.Callable的对象,并通过Spring MVC所管理的线程来产生返回值。与此同时,Servlet容器的主线程则可以退出并释放其资源了,同时也允许容器去处理其他的请求。通过一个TaskExecutor,Spring M

  • 本文向大家介绍如果将axios异步请求同步化处理?相关面试题,主要包含被问及如果将axios异步请求同步化处理?时的应答技巧和注意事项,需要的朋友参考一下

  • 本文向大家介绍详解XMLHttpRequest(一)同步请求和异步请求,包括了详解XMLHttpRequest(一)同步请求和异步请求的使用技巧和注意事项,需要的朋友参考一下 XMLHttpRequest 让发送一个HTTP请求变得非常容易。你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求。当传输完毕后,结果的HTTP状态以及返回的响应内容也可以从请求对象中获取。  通过XML