1

我目前正在使用 Apache Tomcat 作为网络服务器在 Java EE 中构建一个新的网络应用程序。我在工作中使用 jsps 和 servlet。

我的问题是:

我有一个非常标准的业务逻辑。没有一个是同步的,在任何给定时间只会运行我的网络应用程序逻辑的一个线程吗?

由于使所有功能“同步”会导致巨大的开销,是否有任何替代方案?

如果我的项目中有一个静态方法。这使事情变得非常简单,例如:

       for (int i=0;i<10000;i++ ) {
           counter++;
       }

如果该方法不是线程安全的,那么这种方法在多用户应用程序中的行为是什么?是出乎意料的行为吗?!

再次以简单的方式:

如果我的意思是构建一个多用户 Web 应用程序,我应该“同步”我项目中的所有内容吗?如果不是全部,我应该同步什么?

4

1 回答 1

2

在任何给定时间,我的网络应用程序逻辑只会运行一个线程吗?

不,servlet 容器将只为每个 servlet 创建一个实例,并doService()从多个线程调用该 servlet 的方法。默认情况下,在 Tomcat 中,您可以预期多达 200 个线程同时调用您的 servlet。

如果 servlet 是单线程的,那么您的应用程序将会非常缓慢,请参阅SingleThreadModel- 出于某种原因已弃用。

使所有功能“同步”会产生巨大的开销,有什么替代方法吗?

有 - 你的代码应该是线程安全的或更好的 - 无状态的。请注意,如果您的 servlet 没有任何状态(如可变字段 - 不寻常),则可以由多个线程安全地访问它。这同样适用于几乎所有对象。

在带有for循环的示例代码中 - 如果counter是局部变量,则此代码是线程安全的。如果是字段,则不安全。每个线程都有一个局部变量的本地副本,而访问同一对象的所有线程同时访问相同的字段(并且需要同步)。

我应该同步什么?

可变的、全局的、共享的状态。例如,在您的示例代码中,如果counter是一个字段并且是从多个线程修改的,则递增它必须是同步的(考虑AtomicInteger)。

于 2012-06-10T11:56:48.983 回答