java在服务器上并行运行服务
我有一个处理用户请求的服务 这个服务调用另一个外部后端系统(web服务)。但我需要并行执行这些后端web服务。你会怎么做?最好的方法是什么 提前谢谢 -----编辑 后端系统可以并行运行请求,我们使用容器(tomcat用于开发)和websphere finally用于生产。 所以我已经在一个线程(servlet)中,需要生成两个任务,并尽可能紧密地并行运行它们java在服务器上并行运行服务,java,concurrency,Java,Concurrency,我有一个处理用户请求的服务 这个服务调用另一个外部后端系统(web服务)。但我需要并行执行这些后端web服务。你会怎么做?最好的方法是什么 提前谢谢 -----编辑 后端系统可以并行运行请求,我们使用容器(tomcat用于开发)和websphere finally用于生产。 所以我已经在一个线程(servlet)中,需要生成两个任务,并尽可能紧密地并行运行它们 我可以想象将quartz或线程与执行器一起使用,或者将其放在Servlet引擎上。在这种情况下,什么是正确的路径?您可以使用线程来并行
我可以想象将quartz或线程与执行器一起使用,或者将其放在Servlet引擎上。在这种情况下,什么是正确的路径?您可以使用
线程来并行运行请求
根据您想要做的事情,在一些现有技术(如servlet)的基础上构建可能是有意义的,这些技术可以为您执行线程处理Heiko是正确的,您可以使用线程。线程是复杂的野兽,需要小心对待。最好的解决方案是使用标准库,如java.util.concurrent。这将是管理并行操作的一种更健壮的方法。这种方法带来了一些性能优势,例如线程池。如果您可以使用这样的解决方案,这将是推荐的方法
如果您想自己执行,这里有一个非常简单的方法来并行执行多个线程,但可能不是很健壮。您需要更好地处理超时和线程破坏等问题
public class Threads {
public class Task implements Runnable {
private Object result;
private String id;
public Task(String id) {
this.id = id;
}
public Object getResult() {
return result;
}
public void run() {
System.out.println("run id=" + id);
try {
// call web service
Thread.sleep(10000);
result = id + " more";
} catch (InterruptedException e) {
// TODO do something with the error
throw new RuntimeException("caught InterruptedException", e);
}
}
}
public void runInParallel(Runnable runnable1, Runnable runnable2) {
try {
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
t1.join(30000);
t2.join(30000);
} catch (InterruptedException e) {
// TODO do something nice with exception
throw new RuntimeException("caught InterruptedException", e);
}
}
public void foo() {
Task task1 = new Task("1");
Task task2 = new Task("2");
runInParallel(task1, task2);
System.out.println("task1 = " + task1.getResult());
System.out.println("task2 = " + task2.getResult());
}
}
答案是在单独的线程中运行任务
对于这种情况,我认为您应该使用池大小有限制的ThreadPoolExecutor
,而不是自己创建线程
代码看起来像这样。(请注意,这只是一个草图。请查看javadocs以了解详细信息,了解数字的含义等。)
//创建执行器。。。这需要由servlet线程共享。
Executor exec=新的线程池Executor(1,10,120,TimeUnit.SECONDS,
新的ArrayBlockingQueue(100),ThreadPoolExecutor.CallerRunPolicy);
//准备第一项任务
最终ArgType someArg=。。。
FutureTask任务=新建FutureTask(
新的可调用(){
公共结果类型调用(){
//使用“someArg”中的信息调用远程服务
返回一些结果;
}
});
执行(任务);
//重复上面的第二个任务
...
执行(任务2);
//等待结果
ResultType res=task.get(30,时间单位:秒);
ResultType res2=task2.get(30,时间单位:秒);
上面的代码并不试图处理异常,您需要对超时进行更复杂的处理;e、 g.跟踪总体请求时间,如果时间过长,则取消任务
这不是石英设计用来解决的问题。Quartz是一个作业调度系统。你只是有一些任务需要尽快执行。。。有可能取消这些请求。您的服务是否已经处理了并行请求?此外,您的web服务很可能已经在支持多线程的容器中运行。。在不了解全局的情况下,很难说任何具体的事情,也许你可以再详细一点?我能保证这些servlet将并行运行吗。如果服务器决定同时运行不同的servlet该怎么办。我只需要运行我的?您可以在servlet容器(例如Tomcat或Jetty)中运行servlet。当一个请求进入时,它被分派到servlet,servlet生成一个线程,在该线程中完成工作。当更多的请求并行进来时,就会产生更多的线程。工作完成后,servlet容器要么销毁线程,要么将其放入池中以供将来重用。但是,如果必须有多个线程(servlet),我的第一个并行运行任务将首先执行,第二个可以最后执行(在所有其他线程(servlet)之后)将被处理,对吗?因此可能会有巨大的延迟。我想这是在您的真实场景中需要解决的问题。servlet概念在许多情况下都非常有效。
// Create the executor ... this needs to be shared by the servlet threads.
Executor exec = new ThreadPoolExecutor(1, 10, 120, TimeUnit.SECONDS,
new ArrayBlockingQueue(100), ThreadPoolExecutor.CallerRunsPolicy);
// Prepare first task
final ArgType someArg = ...
FutureTask<ResultType> task = new FutureTask<ResultType>(
new Callable<ResultType>() {
public ResultType call() {
// Call remote service using information in 'someArg'
return someResult;
}
});
exec.execute(task);
// Repeat above for second task
...
exec.execute(task2);
// Wait for results
ResultType res = task.get(30, TimeUnit.SECONDS);
ResultType res2 = task2.get(30, TimeUnit.SECONDS);