典型的J2ee Web应用程序或基于顶级java构建的任何Web应用程序是多线程应用程序,所以每次编写一些代码时我都要记住竞争条件或并发修改吗?
答案 0 :(得分:2)
典型的J2ee Web应用程序或基于顶级java构建的任何Web应用程序是多线程应用程序吗?
是的,确实如此。但是应用程序服务器(Tomcat,JBoss,WebSphere等)为您处理线程和资源,因此您可能不担心竞争条件或并发修改。
何时应该担心并发修改?例如,如果您碰巧在Servlet中创建了一个字段,并且在每个请求(servlet的doPost
或doGet
方法)上更新了该字段,那么其pc中的两个用户就可以执行请求同一个URL,此字段将具有意外的值。这包括:How do servlets work? Instantiation, sessions, shared variables and multithreading,接受答案的Threadsafety部分。请注意,使用这样的设计是一种不好的做法。
另一种情况可能是您自己在这些线程之间共享新线程和资源。这不是一个好的做法,也不是一个坏的做法,它有点你必须了解你所承担的风险并承担后果。这意味着,您可以自己拥有Servlet和防火线程,但是您可以通过正确的方式处理此问题。请注意,您应该评估是否确实需要在Java EE应用程序中触发和处理线程,或者您是否可以使用其他方法,例如触发将并行和异步处理多个请求的JMS消息。
Thread
的新实例,也不能使用ExecutorService
或任何其他。在代码中:
@Stateless
public class FooEJB {
public void bar() {
//this is not allowed!
Thread t = new Thread(new Runnable() {
//implementation of runnable
});
t.start();
}
public void baz() {
//this is not allowed either!
final int numberOfThreads = ...;
ExecutorService es = Executors.newFixedThreadPool(numberOfThreads);
es.execute(new Runnable() { ... });
es.shutdown();
}
}
答案 1 :(得分:1)
与Java中的几乎任何框架(服务器应用程序,包含Web框架或基于AWT或Swing的GUI应用程序)一样,Java EE是多线程的。但你的问题的答案是否定的:你不必关心竞争条件或同时修改。当然,不允许你犯一些错误(比如共享Servlet变量),但在典型的应用程序中你不关心这些事情。例如,EJB规范禁止使用线程,但它具有异步作业的机制。摘自EJB规范:
企业bean不得尝试管理线程。企业 bean不得尝试启动,停止,暂停或恢复线程,或者 更改线程的优先级或名称。企业bean一定不能 尝试管理线程组。
JPA规范(EntityManager)中最常用的接口也不是线程安全的,尽管其他接口也是。
答案 2 :(得分:0)
在Java EE应用程序容器中,Server负责处理线程。通常,每个请求创建一个线程。但是,使用Spring或EJB,您可以为线程声明不同的范围。因此,您不必直接管理JavaEE应用程序中的线程。