การสร้างเธรดในคอนเทนเนอร์ JavaEE EJB/Web

ฉันอ่านหนังสือ JavaEE night hacks ของ Adam Bien ว่าในขณะที่การสร้างเธรดนั้นถูกห้ามบนคอนเทนเนอร์ EJB แต่นี่ไม่ใช่กรณีของคอนเทนเนอร์บนเว็บ เขาสร้างตัวดำเนินการเธรดพูลในโพรบเอ็กซ์เรย์ของเขาซึ่งทำงานบน Tomcat

ตอนนี้ฉันสับสนเล็กน้อย แม้ว่าฉันจะเผชิญกับสถานการณ์ที่ฉันต้องทำการจัดการเธรดพูลด้วยตนเองในแอป EE แต่ฉันก็สามารถเข้าใจได้ว่าทำไมการสร้างเธรดด้วยตนเองในคอนเทนเนอร์ JavaEE จึงเป็นความคิดที่ไม่ดี อย่างไรก็ตาม ฉันไม่เข้าใจความแตกต่างระหว่างคอนเทนเนอร์ EJB และคอนเทนเนอร์เว็บเกี่ยวกับการสร้างเธรด เมื่อคุณสามารถปรับใช้ EJB ส่วนใหญ่กับคอนเทนเนอร์ใดคอนเทนเนอร์หนึ่งได้ หากไม่มีอะไรผิดปกติกับเธรดการวางไข่ของเซสชัน bean ในเว็บคอนเทนเนอร์ ปัญหาใดที่อาจเกิดจากการปรับใช้เซสชัน bean เดียวกันกับคอนเทนเนอร์ EJB


person Arash Shahkar    schedule 31.10.2012    source แหล่งที่มา


คำตอบ (3)


นี่คือจุดที่ส่วน "Enterprise" ของ Java EE มาบรรจบกับโลกแห่งความเป็นจริง

สถานที่ตั้งของการใช้ระบบ "องค์กร" ส่วนใหญ่เน้นไปที่การจัดการ ยกการตัดสินใจและการกำหนดค่าให้กับคอนเทนเนอร์โดยเฉพาะ แทนที่จะอาศัยแอปพลิเคชันในการจัดการทรัพยากรเหล่านี้ ด้วยการแยกการสร้างและการจัดการทรัพยากรออกจากรหัสแอปพลิเคชันและอาศัยคอนเทนเนอร์ ผู้ดูแลระบบจึงมีการมองเห็นและเข้าถึงทรัพยากรเหล่านั้น จึงมีศักยภาพในการปรับแต่งและติดตามแอปพลิเคชันในระดับที่สูงกว่าและในลักษณะทั่วไป มากกว่าการใช้กลไกเฉพาะของแอปพลิเคชันสำหรับสิ่งนี้

นั่นคือสภาพแวดล้อมที่เราอยู่ และนั่นเป็นส่วนหนึ่งของสิ่งที่ขับเคลื่อน "กฎ" เหล่านี้ของข้อกำหนดเฉพาะ Java EE เกี่ยวกับสิ่งที่คุณทำได้และไม่สามารถ (ไม่ควร) ทำได้

ตอนนี้สเป็คคอนเทนเนอร์เซิร์ฟเล็ตมีความดุร้ายมากขึ้นทางตะวันตก ไม่มีคุณลักษณะการจัดการ "องค์กร" ทั้งหมดเหล่านี้ (โปรดทราบว่าคอนเทนเนอร์จำนวนมากเปิดเผยคุณลักษณะเหล่านี้ แต่ข้อมูลจำเพาะไม่ได้กล่าวถึง) ตัวอย่างเช่น การให้บริการไฟล์แบบคงที่นั้นเป็นความสามารถแบบ bread and Butter ของเว็บคอนเทนเนอร์ ดังนั้นจึงแทบจะไม่สมเหตุสมผลเลยที่จะจำกัดการเข้าถึงไฟล์ดังกล่าวโดยนักพัฒนา นอกจากนี้ ข้อมูลจำเพาะของเซิร์ฟเล็ตยังมาก่อนข้อมูลจำเพาะของ EJB และถูกยึดเข้ากับสภาพแวดล้อมแทนที่จะทำใหม่เมื่อคำนึงถึงสภาพแวดล้อมนั้น

นั่นให้ข้อกำหนดที่ "ขัดแย้ง" สองประการแก่คุณในแง่ของสิ่งเฉพาะ (เช่นเธรด)

ใช่แล้ว ข้อมูลจำเพาะของ Servlet "ช่วยให้คุณ" จัดการกลุ่มเธรดของคุณเองได้ แม้ในแอป Java EE แม้ว่ากลุ่มเธรดเหล่านั้นน่าจะอยู่ใน JVM เดียวกันทุกประการ (และทำให้ "ใช้ทรัพยากร Java EE" อย่างไม่สามารถจัดการได้) เป็น คอนเทนเนอร์ Java EE

ความหมายในโลกแห่งความเป็นจริงก็คือ ใช่ หากคุณต้องการ คุณสามารถสปูลเธรดและสิ่งดังกล่าวภายในคอนเทนเนอร์ Java EE หรือในคอนเทนเนอร์เซิร์ฟเล็ตได้ ไม่มีคอนเทนเนอร์ยอดนิยมใดที่ห้ามไม่ให้คุณทำเช่นนี้ (WebSphere อาจ แต่ฉันไม่ได้ใช้)

แต่คุณไม่ควร Java EE (โดยเฉพาะ Java EE 6) มีกลไกและห่วงที่คุณสามารถข้ามไปทำสิ่งต่าง ๆ แทนการใช้เธรดพูล สิ่งต่างๆ เช่น WorkManagers, คิว JMS, Asynchronous Session bean, งาน Timer

ในแอปเซิร์ฟเล็ต กลไกเหล่านี้ส่วนใหญ่ไม่มีอยู่ ดังนั้นคุณจึงไม่สามารถใช้ประโยชน์จากกลไกเหล่านี้ได้ และด้วยเหตุนี้คุณจึงใช้ "แค่ Java" แทน

การขยายสาขาของการใช้ "Just Java" ในเว็บแอปที่ปรับใช้กับแอป Java EE คือการมองเห็นภายในคอนเทนเนอร์ เว็บแอปของคุณจะต้องมีตัวแปรการกำหนดค่าของตัวเองเพื่อตั้งค่าขนาดของเธรดพูล เป็นต้น และไม่สามารถพึ่งพาคอนเทนเนอร์ในการจัดการสิ่งนั้นได้

ท้ายที่สุดแล้ว มันก็มักจะไม่มีเรื่องใหญ่ ความซับซ้อนส่วนใหญ่ของ Java EE มุ่งเน้นไปที่ความสามารถในการจัดการที่คนส่วนใหญ่ไม่ได้ใช้ สำหรับตัวฉันเอง ฉันใช้ Java EE และไม่ค่อยได้ใช้ ol WAR ธรรมดาเลย ฉันชอบที่จะผลักดันคอนเทนเนอร์ให้มากที่สุดเท่าที่จะทำได้ -- ปล่อยให้มันทำงานได้ อย่างไรก็ตาม ฉันมีเซิร์ฟเวอร์ซ็อกเก็ตแบบกำหนดเองที่ทำงานใน WAR ในคอนเทนเนอร์ Java EE ซึ่งทำลายทุกกฎเกณฑ์เท่าที่จะจินตนาการได้ เพียงเพราะมันทำได้ง่ายกว่ามาก "วิถี Java EE" นั้นไม่ยืดหยุ่นพอสำหรับสิ่งที่เราต้องการทำ ดังนั้นเราจึงใช้ "แค่ Java" และเทโค้ดลงใน WAR เพื่อที่เราจะได้เล่นใน Wild Wild West ที่ซึ่ง Men เป็น Men และ จัดการกระทู้ของตัวเอง

person Will Hartung    schedule 31.10.2012
comment
ขอบคุณสำหรับคำตอบที่ครอบคลุมของคุณ Will ฉันไม่มีความเชี่ยวชาญมากนักใน Java EE แต่ฉันไม่คิดว่าความง่ายจะเป็นเหตุผลในการฝ่าฝืนกฎเหล่านี้เสมอไป แม้ว่าแพลตฟอร์มจะมีความครอบคลุมก็ตาม - person Arash Shahkar; 31.10.2012

EJB ได้รับการจัดการโดยเซิร์ฟเวอร์ การจัดการหมายถึงการฉีดการพึ่งพา หากคุณสร้างเธรดจากคลาสโดยใช้คำอธิบายประกอบ เซิร์ฟเวอร์จะไม่สามารถจัดการเธรดเหล่านั้นได้ (ทำ @PostConstruct, แทรกการอ้างอิง ฯลฯ)

person Przemysław Kowalczyk    schedule 31.10.2012
comment
มันเป็นปัญหาเดียวเหรอ? หากฉันต้องการดำเนินการคำนวณแบบมัลติเธรดหรือการดำเนินการเครือข่ายโดยไม่จำเป็นต้องใช้สิ่งอำนวยความสะดวกที่จัดการโดยคอนเทนเนอร์ การสร้างเธรดพูลด้วยตนเองถือเป็นแนวปฏิบัติที่ดีหรือไม่ - person Arash Shahkar; 31.10.2012
comment
เธรดพูลได้รับการจัดการโดยเซิร์ฟเวอร์ / คอนเทนเนอร์ และควรเป็นเช่นนั้น คุณแน่ใจหรือว่าการคำนวณของคุณไม่สามารถทำได้โดย stateful bean หรือไร้สัญชาติ? เพราะนั่นคือปรัชญาของ Enterprise Java Beans - ลืมเรื่องเธรดไปเลย ใช้ bean แต่ไม่ใช่ว่าคุณไม่สามารถสร้างเธรดในคอนเทนเนอร์ EJB ได้... - person Przemysław Kowalczyk; 31.10.2012
comment
นอกจากนี้เท่าที่ฉันจำได้ (ไม่พบการอ้างอิงที่แน่นอน) คอนเทนเนอร์ EJB ใช้หน่วยความจำมากที่สุดเท่าที่จะเป็นไปได้ (และจัดการมัน) ดังนั้นการสร้างเธรดที่ต้องการหน่วยความจำมากอาจทำให้เกิดข้อยกเว้นหน่วยความจำไม่เพียงพอ เนื่องจากคอนเทนเนอร์ทำ ไม่ปล่อยมันเหมือนกับที่ทำกับอ็อบเจ็กต์อื่น ๆ ที่มันจัดการ - person Przemysław Kowalczyk; 31.10.2012

EJB จะถูกดำเนินการในคอนเทนเนอร์ EJB เสมอ ดังนั้นจึงไม่ควรสร้างเธรดใน EJB ด้วยตนเอง แม้ว่าจะเป็นแพ็คเกจในรูปแบบไฟล์ WAR (เว็บโมดูล) แต่จะถูกดำเนินการในคอนเทนเนอร์ EJB และมีข้อจำกัดเดียวกันเกี่ยวกับการสร้างเธรด

อย่างไรก็ตาม เซิร์ฟเล็ตและตัวกรองจะดำเนินการในคอนเทนเนอร์ของเว็บ และไม่มีสิ่งใดห้ามไม่ให้มีเธรดพูลที่จัดการด้วยตนเอง

person Arash Shahkar    schedule 31.10.2012