如果synchronized
方法中存在service()
块,例如在struts的ActionServlet
中,如果多个请求/线程是一个拥有大量数字的繁忙站点,它将如何工作?点击。
每个线程是否会等待下一个线程从同步块释放锁定?会不会造成响应延迟
答案 0 :(得分:5)
不要同步servlet的服务方法。
如果您同步servlet的service
方法,实际上您正在为该Servlet实例一次为一个线程进行“访问保留”。
Struts ActionServlet
类是HttpServlet
,基本上doGet
和doPost
方法在这里很有用。如果我们要讨论Struts,process方法是主要入口点,但同样的原则适用于所有方法,就像它对一般service
方法一样。
这个想法是这样的。
在web.app
中声明servlet时,servlet容器(例如Tomcat)将只创建该servlet的一个实例。这意味着只有一个实例可以提供所有请求。
如果有更多请求同时到达,则每个请求线程都有机会获得service
方法,因为没有强制执行同步。
如果您有10个请求线程,则每个线程将在service
方法中并发执行。这通常是安全的,因为在service
方法中完成的处理不涉及与其正在处理的当前请求相关的任何状态。如果向servlet添加状态,则会遇到问题。 Here is an article with more details on the subject。
现在回到Struts 。
Struts使用名为Front Controller的模式,ActionServlet
是该控制器。这将依次将特定请求委派给其配置中指定的特定Action
类(a.k.a struts-config.xml
)。
所有传入的请求都在此处传递。如果此时放置同步(Struts process
方法或servlet service
方法更高),则一次为一个线程保留servlet。 对于struts,您一次保留对单个线程的所有请求处理。
这意味着如果10个请求同时到达,在没有同步的情况下都可以并行执行,而在同步请求2的情况下,必须等到请求1完成,3等待2等等(即顺序处理请求)。这意味着表现不佳。
也许对于提出请求1的幸运用户来说,没有性能影响,但是10号将不得不等待。那么100号怎么样? 200?
如果您在编写应用程序时考虑到线程安全性,则无需同步入口点。如果您的应用程序是您无法避免同步的类型,那么同步入口点将降低性能。
P.S。还有一件事。如果您考虑在流程中将同步降低,即Action
类,请注意它们也不是线程安全的,并且存在only one instance of it inside the Struts framework。