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

时间:2017-12-17 08:45:45

标签: java spring multithreading spring-mvc

我使用SPRING使用REST调用Java Web应用程序。

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

所以我添加了Thread config:

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

我使用的是Sync服务而不是Async,我测试了它并没有限制处理请求的线程,它同时处理它们。

我期待的是当我一次发送2个请求时 - 第二个请求将被抛出或者它将等到第一个请求完成。

我根本没有在我的应用程序中实现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 个答案:

答案 0 :(得分:2)

问题是在配置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();
}

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

答案 1 :(得分:1)

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

@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