我使用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
我在这里缺少什么?
答案 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