दिलचस्प पोस्ट
कोणीय एचटीटीपी समझौता: `सफलता` /` त्रुटि` पद्धतियों और `फिर` के तर्कों में अंतर मेथमैटिका में रनटाइम त्रुटियों के हिमस्खलन को रोकना कंसैकेट स्थिति के साथ MySQL चुनें MySQL अनजान कॉलम ऑन क्लॉज कैसे JQuery-AJAX अनुरोध तुल्यकालिक बनाने के लिए मैं iPhone पर CoreData सामग्री कैसे एन्क्रिप्ट कर सकता हूँ एक प्रक्रिया पेड़ को समाप्त करें (सी के लिए Windows) जीएसएन – जेसन से एक टाइप ऐरेलिस्ट <टी> में परिवर्तित करें ASP.NET से सभी ब्राउज़र के लिए ब्राउज़र कैशिंग अक्षम करना Jfreechart के साथ समय श्रृंखला बनाना जावा में MANIFEST.MF फ़ाइल का उपयोग करें `नई ऑब्जेक्ट () 'और ऑब्जेक्ट आर्टिकल नोटेशन के बीच अंतर क्या है? सरणी को इनिशियलाइज़ करने के लिए मैं सदस्य प्रारंभिक सूची का उपयोग कैसे कर सकता हूं? मैं ggplot (किंवदंतियों के साथ) में लगातार-चौड़ाई भूखंड कैसे बना सकता हूं? CSS और JQUERY के साथ एक स्लाइड शो के माध्यम से एकाधिक पृष्ठभूमि छवियों को बनाने की कोशिश कर रहा है

क्या JSF प्रबंधित बीन में एक नया धागा शुरू करना सुरक्षित है?

मुझे एक निश्चित जवाब नहीं मिल सका है कि क्या यह सत्र-स्कैड JSF प्रबंधित बीन्स के अंदर थ्रेड्स अंडरफ़ॉर्म करने के लिए सुरक्षित है। धागा को स्टेटलेस ईजेबी उदाहरण (जो प्रबंधित बीन पर निर्भरता-इंजेक्शन था) पर तरीके कॉल करने की आवश्यकता है।

पृष्ठभूमि यह है कि हमारे पास एक ऐसी रिपोर्ट है जो उत्पन्न करने में काफी समय लगता है। यह सर्वर सेटिंग के कारण HTTP अनुरोध को टाइम-आउट करने की वजह से हम बदल नहीं सकते हैं। तो यह विचार एक नया धागा शुरू करना है और इसे रिपोर्ट तैयार करने और इसे अस्थायी रूप से संग्रहीत करने के लिए। इस बीच जेएसएफ पृष्ठ प्रगति बार दिखाता है, पीढ़ी पूरी हो जाने तक प्रबंधित बीन का चुनाव करता है और फिर संग्रहीत रिपोर्ट को डाउनलोड करने का दूसरा अनुरोध करता है। यह काम करने लगता है, लेकिन मुझे यकीन है कि मैं क्या कर रहा हूं यह हैक नहीं है।

Solutions Collecting From Web of "क्या JSF प्रबंधित बीन में एक नया धागा शुरू करना सुरक्षित है?"

परिचय

एक सत्र के भीतर से निकाले जाने वाले थ्रेड्स प्रबंधित बीन अनिवार्य रूप से एक हैक नहीं है, जब तक यह आपकी इच्छानुसार काम करता है। लेकिन अपनी जरूरतों पर चलने वाले धागे को अत्यधिक देखभाल के साथ किया जाना चाहिए कोड को उस तरीके से नहीं लिखा जाना चाहिए जिस तरह से एक उपयोगकर्ता उदाहरण के लिए सत्र के लिए असीमित मात्रा में धागे पैदा कर सकता है और / या यह कि सत्र समाप्त हो जाने के बाद भी थ्रेड्स चलते रहेंगे। यह आपके आवेदन को अभी या बाद में उड़ा देगा।

कोड को इस तरह लिखा जाना चाहिए कि आप यह सुनिश्चित कर सकते हैं कि कोई उपयोगकर्ता उदाहरण के लिए कभी भी एक से अधिक पृष्ठभूमि धागा प्रति सत्र नहीं पैदा कर सकता है और यह भी कि जब भी सत्र नष्ट हो जाता है तो बाधित होने की गारंटी दी जाती है। एक सत्र के भीतर कई कार्यों के लिए आपको कार्य कतार की आवश्यकता होती है।

इसके अलावा, सभी थ्रेड्स को आम तौर पर एक सामान्य थ्रेड पूल द्वारा परोसा जाना चाहिए ताकि आप एप्लिकेशन स्तर पर स्पॉन्ड धागे की कुल राशि पर सीमा डाल सकें। औसत जावा ईई अनुप्रयोग सर्वर एक कंटेनर प्रबंधित थ्रेड पूल प्रदान करता है जिसके माध्यम से आप अन्य ईजेबी के @Asynchronous और @Schedule @Asynchronous बीच उपयोग कर सकते हैं। कंटेनर स्वतंत्र होने के लिए, आप इसके लिए जावा 1.5 की यूटीआईटी समवर्ती ExecutorService और ScheduledExecutorService ExecutorService भी उपयोग कर सकते हैं।

नीचे उदाहरण ईजेबी के साथ जावा ईई 6+ मानते हैं

फायर और फार्म सबमिट पर एक कार्य भूल जाओ

 @Named @RequestScoped // Or @ViewScoped public class Bean { @EJB private SomeService someService; public void submit() { someService.asyncTask(); // ... (this code will immediately continue without waiting) } } 
 @Stateless public class SomeService { @Asynchronous public void asyncTask() { // ... } } 

पेज लोड पर एसिंक्रोनस मॉडल लाएं

 @Named @RequestScoped // Or @ViewScoped public class Bean { private Future<List<Entity>> asyncEntities; @EJB private EntityService entityService; @PostConstruct public void init() { asyncEntities = entityService.asyncList(); // ... (this code will immediately continue without waiting) } public List<Entity> getEntities() { try { return asyncEntities.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new FacesException(e); } catch (ExecutionException e) { throw new FacesException(e); } } } 
 @Stateless public class EntityService { @PersistenceContext private EntityManager entityManager; @Asynchronous public Future<List<Entity>> asyncList() { List<Entity> entities = entityManager .createQuery("SELECT e FROM Entity e", Entity.class) .getResultList(); return new AsyncResult<>(entities); } } 

यदि आप जेएसएफ यूटिलिटी लाइब्रेरी OmniFaces का उपयोग कर रहे हैं, तो यह अधिक तेज़ हो सकता है यदि आप प्रबंधित बीन @Eager साथ एनोटेट करते हैं

आवेदन शुरू करने पर पृष्ठभूमि की नौकरियां शेड्यूल करें

 @Singleton public class BackgroundJobManager { @Schedule(hour="0", minute="0", second="0", persistent=false) public void someDailyJob() { // ... (runs every start of day) } @Schedule(hour="*/1", minute="0", second="0", persistent=false) public void someHourlyJob() { // ... (runs every hour of day) } @Schedule(hour="*", minute="*/15", second="0", persistent=false) public void someQuarterlyJob() { // ... (runs every 15th minute of hour) } @Schedule(hour="*", minute="*", second="*/30", persistent=false) public void someHalfminutelyJob() { // ... (runs every 30th second of minute) } } 

लगातार पृष्ठभूमि में आवेदन विस्तृत मॉडल को अपडेट करें

 @Named @RequestScoped // Or @ViewScoped public class Bean { @EJB private SomeTop100Manager someTop100Manager; public List<Some> getSomeTop100() { return someTop100Manager.list(); } } 
 @Singleton @ConcurrencyManagement(BEAN) public class SomeTop100Manager { @PersistenceContext private EntityManager entityManager; private List<Some> top100; @PostConstruct @Schedule(hour="*", minute="*/1", second="0", persistent=false) public void load() { top100 = entityManager .createNamedQuery("Some.top100", Some.class) .getResultList(); } public List<Some> list() { return top100; } } 

यह भी देखें:

  • एक जेएसएफ में स्पॉइंग थ्रेड्स अनुक्रमित कार्य के लिए टाइमर का इस्तेमाल करते हुए बीन प्रबंधित करते थे

ईजेबी 3.1 @Asynchronous methods । यह वही है जो वे इसके लिए हैं।

छोटा उदाहरण जो OpenEJB 4.0.0-SNAPSHOTs का उपयोग करता है। यहां हमारे पास एक @Singleton बीन है @Singleton एक विधि के रूप में चिह्नित किया गया है जो @Asynchronous । हर बार जब विधि किसी के द्वारा लागू की जाती है, तो इस मामले में आपका जेएसएफ प्रबंधित बीन, यह तुरंत वापस लौटाएगा चाहे कितनी देर तक विधि वास्तव में ले जाती है।

 @Singleton public class JobProcessor { @Asynchronous @Lock(READ) @AccessTimeout(-1) public Future<String> addJob(String jobName) { // Pretend this job takes a while doSomeHeavyLifting(); // Return our result return new AsyncResult<String>(jobName); } private void doSomeHeavyLifting() { try { Thread.sleep(SECONDS.toMillis(10)); } catch (InterruptedException e) { Thread.interrupted(); throw new IllegalStateException(e); } } } 

यहाँ एक छोटे से @Asynchronous जो कि एक बार में @Asynchronous विधि को कई बार आमंत्रित करता है

प्रत्येक अभिविन्यास एक भविष्य वस्तु देता है जो अनिवार्य रूप से खाली शुरू होता है और उसके बाद के मान कंटेनर द्वारा भरेगा जब संबंधित विधि कॉल वास्तव में पूर्ण हो जाएंगे।

 import javax.ejb.embeddable.EJBContainer; import javax.naming.Context; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class JobProcessorTest extends TestCase { public void test() throws Exception { final Context context = EJBContainer.createEJBContainer().getContext(); final JobProcessor processor = (JobProcessor) context.lookup("java:global/async-methods/JobProcessor"); final long start = System.nanoTime(); // Queue up a bunch of work final Future<String> red = processor.addJob("red"); final Future<String> orange = processor.addJob("orange"); final Future<String> yellow = processor.addJob("yellow"); final Future<String> green = processor.addJob("green"); final Future<String> blue = processor.addJob("blue"); final Future<String> violet = processor.addJob("violet"); // Wait for the result -- 1 minute worth of work assertEquals("blue", blue.get()); assertEquals("orange", orange.get()); assertEquals("green", green.get()); assertEquals("red", red.get()); assertEquals("yellow", yellow.get()); assertEquals("violet", violet.get()); // How long did it take? final long total = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); // Execution should be around 9 - 21 seconds assertTrue("" + total, total > 9); assertTrue("" + total, total < 21); } } 

उदाहरण स्रोत कोड

कवर के तहत जो यह काम करता है:

  • JobProcessor जो कॉलर देखता है वह वास्तव में JobProcessor का एक उदाहरण नहीं है इसके बजाय यह एक उपवर्ग या प्रॉक्सी है जिसमें सभी तरीकों को ओवरराइड किया गया है। असिंक्रोनस होने वाले तरीके अलग तरीके से नियंत्रित किए जाते हैं।
  • एक अतुल्यकालिक विधि को कॉल करने के परिणामस्वरूप केवल एक Runnable बनाया जा सकता है जो आपके द्वारा दी गई विधि और पैरामीटर को लपेटता है। यह चालन एक निष्पादक को दिया जाता है जो केवल एक थ्रेड पूल से जुड़ी एक कार्य कतार है।
  • कतार में काम जोड़ने के बाद, विधि का प्रॉक्सी संस्करण Future की एक कार्यान्वयन देता है जो Runnable से जुड़ा हुआ है जो अब कतार पर प्रतीक्षा कर रहा है।
  • जब JobProcessor अंततः असली JobProcessor उदाहरण पर विधि को निष्पादित करता है, तो यह वापसी मूल्य ले जाएगा और Future में इसे कॉलर के लिए उपलब्ध बना देगा।

नोट करने के लिए महत्वपूर्ण है कि AsyncResult ऑब्जेक्ट को JobProcessor देता है वही Future ऑब्जेक्ट कॉलर होल्डिंग नहीं है। यह साफ हो गया होता कि असली JobProcessor String लौटा सकता था और कॉलर के JobProcessor का संस्करण Future<String> लौटा सकता था, लेकिन हमें ऐसा करने का कोई तरीका नहीं दिखाई देता था जिससे बिना जटिलता को जोड़ा जा सके तो AsyncResult एक साधारण आवरण वस्तु है कंटेनर String बाहर खींच कर, AsyncResult दूर फेंक AsyncResult , फिर String को वास्तविक Future में रखकर कॉल करने वाला है।

रास्ते में प्रगति प्राप्त करने के लिए, बस @Asynchronous विधि पर एक थ्रेड-सुरक्षित ऑब्जेक्ट जैसे AtomicInteger को पास करें और बीन कोड को समय-समय पर पूर्ण रूप से अपडेट करें।

मैंने यह कोशिश की और मेरे जेएसएफ प्रबंधन बीन से अच्छा काम किया

 ExecutorService executor = Executors.newFixedThreadPool(1); @EJB private IMaterialSvc materialSvc; private void updateMaterial(Material material, String status, Location position) { executor.execute(new Runnable() { public void run() { synchronized (position) { // TODO update material in audit? do we need materials in audit? int index = position.getMaterials().indexOf(material); Material m = materialSvc.getById(material.getId()); m.setStatus(status); m = materialSvc.update(m); if (index != -1) { position.getMaterials().set(index, m); } } } }); } @PreDestroy public void destory() { executor.shutdown(); }