Nach meinem Verständnis erstellt ein Servlet-Container begrenzte Instanzen von Servlets und mehrere Threads jeder Servlet-Instanz und verwendet diese Threads und Instanzen erneut.
Da es mehrere Instanzen eines Threads gibt, sind diese nicht "Thread-sicher" (obwohl ich verstehe, dass das Codieren mit Thread-Sicherheit nicht schwierig ist).
EJBs-Container dagegen erstellen keine Threads von EJB, sondern nur EJB-Objekte (mit Pool). Da es keine Mehrfach-Threads einer EJB-Instanz gibt, ist die Thread-Sicherheit keine Frage.
Meine Frage: Warum haben Sie ein anderes Verhalten? Ist es keine gute Idee, EJBs als Servlets (Threads unsicher) zu betreiben?
Ich bin mir sicher, dass ich etwas vermisse und diesen fehlenden Teil verstehen will.
Wahrscheinlich, weil sie nicht mit den gleichen Zielen entworfen wurden.
Die Servlet-API ist eine einfache API, die dem HTTP-Protokoll sehr nahe kommt und auf der Sie Anwendungen oder Frameworks erstellen können. Da das HTTP-Protokoll völlig zustandslos ist, war es wahrscheinlich sinnvoll, auch eine statusfreie API zu erstellen. Mehrere Frameworks, die auf der Servlet-API (z. B. Stripes) basieren, verwenden eine Instanz von Aktion pro Anforderung, die nicht gleichzeitig verwendet wird.
EJBs sind ein viel komplexeres Framework auf hoher Ebene, das darauf ausgelegt ist, transaktionale Geschäftslogik so einfach wie möglich zu implementieren. Es ist schwerer und hat Stateful-Komponenten. Diese müssen natürlich threadsicher sein. Ich denke, es war also natürlich, auch statusfreie Bohnen fadensicher zu machen.
Es sollte beachtet werden, dass Spring-Beans beispielsweise standardmäßig Singles sind und daher denselben Regeln wie Servlets folgen müssen. So sind mehrere Designs möglich, um mehr oder weniger die gleiche Funktionalität zu bieten.
Threads haben nichts mit einer Leistungsoptimierung zu tun. Wenn Sie 3 Anfragen gleichzeitig bearbeiten müssen, benötigen Sie 3 Threads, unabhängig davon, ob die Anfrage an ein Servlet oder an ein EJB geht.
Die kürzeste Antwort auf Ihre Frage ist natürlich ist es eine gute Idee, um es möglich, EJBs wie Servlets zu arbeiten und in EJB 3.1 wir eine Komponente hinzugefügt, die genau das tun können, dass: @Singleton
Eine @Singleton
-Bohne kann wie ein Servlet multi-threaded sein, entweder:
@ConcurrencyManagement(BEAN)
@ConcurrencyManagement(CONTAINER)
zusammen mit @Lock(READ)
auf Verfahren, bei denen die Parallelität und @Lock(WRITE)
auf Verfahren gewünscht wird, die nicht sicher sind, fädeln. Eine andere Sache, die Servlets seit Jahren hatten, die EJBs nie hatten, war <load-on-startup>
, was einem Servlet erlaubt, eifrig zu laden und am Anwendungsstart zu arbeiten.
Um das Servlet <load-on-start>
anzupassen, haben wir die Annotation @Startup
hinzugefügt, die zu jedem @Singleton
EJB hinzugefügt werden kann und bewirkt, dass sie beim Start der Anwendung gestartet wird. Bei diesen Beans wird die Methode @PostConstruct
aufgerufen, wenn die Anwendung gestartet wird, und ihre @PreDestroy
wird aufgerufen, wenn die Anwendung beendet wird.
Anstatt eine Nummer zu verwenden ( <load-on-startup>1</load-on-startup>
), den Auftrag zu diktieren, in der mit @Startup
Start kommentierten Bohnen, Sie Bohnen mit @DependsOn
und geben Sie eine Liste von Bohnen, die vor der kommentierten Bohne beginnen müssen mit Anmerkungen versehen können.
Und ein weit weniger bekannt und verstanden Aspekt haben wir EJB 3.1 in auszurichten Servlets und EJBs war natürlich EJBs zu ermöglichen, innerhalb von .war
Dateien verpackt werden - das ist nicht der weniger bekannte Teil - und wenn wir das gemacht haben dass wir die Definition von java:comp/env
im Stillen so geändert haben, dass sie dem Servlet-Ansatz entspricht.
Vor EJB 3.1 gab es keine Möglichkeit, zwei EJBs einen java:comp/env
-Namespace zu teilen ( java:comp/env
ist bean-scoped in der EJB-Spezifikation). Servlets hatten im Gegensatz dazu nie die Möglichkeit, dass einzelne Servlets ihren eigenen privaten java:comp/env
-Namespace hatten ( java:comp/env
ist in der Servlet-Spezifikation modulspezifisch). So in EJB 3.1 ein EJB, die in einem Krieg gepackt ist das gleiche Modul-scoped java:comp/env
Namensraum wie alle anderen Servlets und EJBs in der Webapp haben, was ein ziemlich großer Unterschied zum bohnen scoped ist java:comp/env
Namespace, EJBs wenn sie außerhalb eines Krieges in eine OHR verpackt werden. Wir diskutierten darüber seit Wochen.
Nettes kleines bisschen Bier-Zeit trivial, um deine Freunde zu quizieren.
Ihre beste Antwort ist direkt aus dem Javadoc für das javax.servlet.SingleThreadedModel Schnittstelle:
Veraltet. Ab Java-Servlet-API 2.4 ohne direkten Ersatz.
public interface SingleThreadModel
Stellt sicher, dass Servlets jeweils nur eine Anfrage bearbeiten. Diese Schnittstelle hat keine Methoden.
Wenn ein Servlet diese Schnittstelle implementiert, sind Sie garantiert , dass keine zwei Threads gleichzeitig in der Servlet-Methode des Servlets ausgeführt werden. Der Servlet-Container kann diese Garantie übernehmen, indem er den Zugriff auf eine einzige Instanz des Servlets synchronisiert oder indem er einen Pool von Servlet-Instanzen verwaltet und jede neue Anfrage an ein freies Servlet sendet.
Beachten Sie, dass SingleThreadModel nicht alle Thread-Sicherheitsprobleme löst . Auf Sitzungsattribute und statische Variablen kann beispielsweise immer noch mit mehreren Anforderungen auf mehreren Threads gleichzeitig zugegriffen werden, auch wenn SingleThreadModel-Servlets verwendet werden. Es wird empfohlen, dass ein Entwickler andere Methoden zum Beheben dieser Probleme einbaut, anstatt diese Schnittstelle zu implementieren, z. B. die Verwendung einer Instanzvariablen zu vermeiden oder den Block des Codes, der auf diese Ressourcen zugreift, zu synchronisieren. Diese Schnittstelle ist in der Servlet-API Version 2.4 veraltet.
Tags und Links java multithreading thread-safety servlets ejb