2012-10-01 12 views
10

मुझे वसंत एमवीसी ऐप काम कर रहा है और मैं जो करने की कोशिश कर रहा हूं वह है मेरे ऐप से पृष्ठभूमि कार्य शुरू करना या सबमिट करना।वसंत एमवीसी ऐप से पृष्ठभूमि कार्य सबमिट करना

असल में मैं कार्य को तब तक जारी रखना चाहता हूं जब तक कि यह ऐप पर कुछ और करने का फैसला न करे।

लेकिन अगर मुझे आवश्यकता हो तो मैं कार्य को रोक/मार/रोकना चाहता हूं। चूंकि मैंने ऐसा करने के पहले एक अच्छा/बेहतर तरीका ढूंढने से पहले ऐसा नहीं किया है।

मैं इन उपयोगी पाया:

http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

How do you kill a thread in Java?

Java threads: Is it possible view/pause/kill a particular thread from a different java program running on the same JVM?

तो मैं मेरी पृष्ठभूमि कार्य प्रस्तुत करने के लिए @Async कार्य का उपयोग करना चाहता है, लेकिन सूत्र उपयोग करना चाहता था ' इसे बाद में प्राप्त करने के लिए आईडी और यदि आवश्यक हो तो इसे रोक दें?

क्या यह सही दृष्टिकोण है? मुझे मल्टीथ्रेडिंग के साथ कोई अनुभव नहीं है इसलिए मैं यहां सुनने के लिए हूं।

कोड अद्यतन:

public interface Worker { 
    public void work(); 
    public void cancel(); 
} 

कार्यान्वयन:

परीक्षण प्रयोजनों के लिए
@Component("asyncWorker") 
public class AsyncWorker implements Worker { 

    @Async 
    public void work() { 
     String threadName = Thread.currentThread().getName(); 
     System.out.println(" " + threadName + " beginning work"); 
     try { 
       Thread.sleep(10000); // simulates work 
     } catch (InterruptedException e) { 
      System.out.println("I stopped"); 
     } 
     System.out.println(" " + threadName + " completed work"); 
    } 

    public void cancel() { Thread.currentThread().interrupt(); } 
} 

नियंत्रक:

@ResponseBody 
@RequestMapping("/job/start") 
public String start() { 
    asyncWorker.work(); 
    return "start"; 
} 

@ResponseBody 
@RequestMapping("/job/stop") 
public String stop() { 
    asyncWorker.cancel(); 
    return "stop"; 
} 

जब मैं /job/start पर जाते हैं, मैं और अधिक है कि एक निष्पादन नहीं कर सकते एक साथ कार्य। दूसरा व्यक्ति केवल

पर पहुंचने के बाद ही निष्पादित करना शुरू कर देता है, जब भी मैं /job/stop पर जाता हूं, प्रक्रिया बंद नहीं होती है, मैं यहां क्या खो रहा हूं?

उत्तर

9

थ्रेड ID का प्रयोग बहुत कम स्तर और भंगुर है। यदि आपने @Async annotation (अच्छी पसंद) का उपयोग करने का निर्णय लिया है तो आप कार्य निष्पादन को नियंत्रित करने के लिए Future<T> का उपयोग कर सकते हैं। मूल रूप से अपने विधि लौटाना चाहिए Future<T> बजाय void की:

@Async 
public Future<Work> work() //... 

अब आप कि Futurecancel() या इंतजार कर सकते हैं इसके पूर्ण होने की:

@ResponseBody 
@RequestMapping("/job/start") 
public String start() { 
    Future<Work> future = asyncWorker.work(); 
    //store future somewhere 
    return "start"; 
} 

@ResponseBody 
@RequestMapping("/job/stop") 
public String stop() { 
    future.cancel(); 
    return "stop"; 
} 

मुश्किल हिस्सा किसी भी तरह तो वापस आ future वस्तु स्टोर करने के लिए है यह बाद के अनुरोधों के लिए उपलब्ध है। बेशक आप एक फ़ील्ड या ThreadLocal का उपयोग नहीं कर सकते हैं। आप सत्र में डाल दिया, फिर भी नोट कि Future serializable नहीं है और समूहों भर में काम नहीं करेगा कर सकते हैं।

@Async के बाद से आमतौर पर थ्रेड पूल के द्वारा समर्थित है, तो संभावना है कि आपके कार्य भी शुरू कर दिया है नहीं किया जा सकता है। रद्द करना इसे पूल से हटा देगा। यदि कार्य पहले से ही चल रहा है, आप isInterrupted() धागा झंडा या InterruptedException संभाल cancel() कॉल को खोजने के लिए कर सकते हैं।

+0

@Async के लिए +1। क्या आप http: // static पर एक लिंक जोड़ सकते हैं।springsource.org/spring/docs/3.0.x/reference/scheduling.html? –

+0

@ टोमाज़ Nurkiewicz हैलो प्रतिक्रिया के लिए धन्यवाद। वास्तव में वर्ग 'fooAsync()' के क्रियान्वयन को चलाने के लिए इसे चलाने योग्य बनाने की आवश्यकता है? अगर मैं एक रद्द विधि बनाना चाहता था जो थ्रेड प्रदर्शन पृष्ठभूमि कार्य को बाधित करता है, तो क्या थ्रेड.currentThread()। उस विशेष थ्रेड को बाधित करेगा? क्या आप कृपया एक उदाहरण दे सकते हैं? –

+0

@ डेविड ग्रिंट: निश्चित रूप से, आप एसओ पर किसी भी पोस्ट को संपादित करने के लिए स्वतंत्र हैं (जो आपने पहले ही किया है, धन्यवाद)। –

संबंधित मुद्दे