2010-08-15 5 views
5

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

for (Object data : dataList) { 
    Object result = TheirLibrary.processData(data); 
    store(result); 
} 

प्रक्रियाडेटा आमतौर पर 1 सेकंड अधिकतम लेता है। मैं (मैं धागे का उपयोग कर में अभ्यास नहीं कर रहा हूँ)() के बाद, कहते हैं 10 सेकंड

संपादित एक टाइमर जो processData मारता है स्थापित करने के लिए, मैं एक कोड स्निपेट की सराहना करेंगे चाहते हैं। निष्पादक दृष्टिकोण उपयोगी दिखता है लेकिन मुझे नहीं पता कि कैसे शुरू करना है। मेरे लिए कोड के लिए अधिक पारंपरिक दृष्टिकोण के लिए छद्म कोड भी सामान्य है।

@ स्टीवन स्लेन्स्कर - सुझाव देता है कि जब तक कि तृतीय पक्ष ऐप बाधा उत्पन्न न करे, यह काम नहीं करेगा। दोबारा विस्तार और उदाहरणों की सराहना की जाएगी

EDIT मुझे अपने सहयोगियों सैम एडम्स से सटीक समाधान मिल रहा था, जिसे मैं एक उत्तर के रूप में जोड़ रहा हूं। इसमें अन्य उत्तरों की तुलना में अधिक जानकारी है, लेकिन मैं उन्हें एक वोट दूंगा। मैं सैम को अनुमोदित उत्तर के रूप में चिह्नित करूंगा

+1

क्या यह निश्चित रूप से एक अनंत लूप में है, या इसे अवरुद्ध किया जा सकता है? बंद पुस्तकालय प्रोफाइलिंग मदद कर सकता है (जब तक यह obfusticated नहीं है)। –

+0

@ जिम डाउनिंग हां, इसे अवरुद्ध किया जा सकता है - कोई विचार नहीं क्यों –

+0

यह जेएमएक्स में किया जा सकता है? – amphibient

उत्तर

2

सैम एडम्स मेरा पीछा जवाब भेजा है, जो मेरे द्वारा स्वीकृत एक

Thread thread = new Thread(myRunnableCode); 
thread.start(); 
thread.join(timeoutMs); 
if (thread.isAlive()) { 
    thread.interrupt(); 
} 

और myRunnableCode नियमित रूप से Thread.isInterrupted() की जाँच करता है, और बाहर निकल जाता है सफाई से अगर यह सच देता है।

वैकल्पिक रूप से आप कर सकते हैं:

Thread thread = new Thread(myRunnableCode); 
thread.start(); 
thread.join(timeoutMs); 
if (thread.isAlive()) { 
    thread.stop(); 
} 

लेकिन चूंकि यह खतरनाक है इस विधि मान्य नहीं है।

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop() "यह पद्धति स्वाभाविक असुरक्षित है। Thread.stop के साथ नज़र रखता है कि यह (अनियंत्रित ThreadDeath अपवाद ढेर अप प्रचार का एक स्वाभाविक परिणाम के रूप में) बंद कर दिया गया के सभी अनलॉक करने के लिए कारण बनता है एक धागा रोक। किसी भी अगर इन मॉनीटरों द्वारा पहले संरक्षित वस्तुओं में से एक असंगत स्थिति में थे, क्षतिग्रस्त वस्तुएं अन्य धागे के लिए दृश्यमान हो जाती हैं, संभावित रूप से मनमाना व्यवहार में परिणामस्वरूप। "

मैंने दूसरा कार्यान्वित किया है और यह वही करता है जो मैं वर्तमान में चाहता हूं।

+0

दूसरा समाधान (आप जो कहते हैं कि तुम को क्रियान्वित किया है) समाधान के रूप में एक ही है और टिप्पणी करने के लिए जोड़ा! schoetbi का जवाब –

+0

@ जिम डाउनिंग schoetbi का जवाब छद्म कोड था और सटीक कॉल नहीं दिया (उदाहरण के लिए "जबकि (! सभी धागे समाप्त हो गए)" वास्तविक तरीकों को नहीं देते –

7

कॉल को लाइब्रेरी में किसी अन्य थ्रेड में रखें और टाइमआउट के बाद इस थ्रेड को मार दें। इस तरह आप एक ही समय में कई वस्तुओं को भी खरीद सकते हैं यदि वे एक-दूसरे पर निर्भर नहीं हैं।


संपादित करें: तो तुम बेहतर बनाने और उसे विस्तार करने के लिए है Democode अनुरोध

यह छद्म कोड है। मौसम की जांच करने में त्रुटि भी एक कॉल सफल थी या मदद नहीं होगी।

for (Object data : dataList) { 
    Thread t = new LibThread(data); 
    // store the thread somewhere with an id 
    // tid and starting time tstart 
    // threads 
    t.start(); 
    } 

while(!all threads finished) 
{ 
    for (Thread t : threads) 
    { 
     // get start time of thread 
     // and check the timeout 
     if (runtime > timeout) 
     { 
      t.stop(); 
     } 
    } 
} 

class LibThread extends Thread { 
    Object data; 

    public TextThread(Object data) 
    { 
     this.data = data; 
    } 

    public void processData() 
    { 
     Object result = TheirLibrary.processData(data); 
     store(result); 
    } 
} 
+2

आपने मुझे हराया - मैंने अपना समान उत्तर हटा दिया है, लेकिन मुझे लगता है कि यह उल्लेख करने लायक है कि शामिल होने (टाइमआउट) का उपयोग करके आप काफी लंबे समय तक प्रतीक्षा करेंगे ... –

+1

+1 उचित होने के लिए। बैंडविड्थ सब कुछ है :-) – schoetbi

+0

मैं एक संक्षिप्त कोड उदाहरण (पीटरएमआर) –

10

ExecutorService.invokeAll(...) तरीकों में से एक एक टाइमआउट तर्क लेता है। एक कॉल करने योग्य बनाएं जो लाइब्रेरी को कॉल करता है, और इसे उस विधि में तर्क के रूप में सूची में लपेटें। भविष्य वापस आ गया कि यह कैसे चला गया।

(नोट: मेरे द्वारा अपरीक्षित)

+0

की सराहना करता हूं, यह एक +1 दिया गया क्योंकि यह वह तरीका था जिसे मैं लिखने वाला था। शायद यह समझाने के लिए कुछ कोड के साथ कर सकता है कि यह सब कैसे काम करता है। लेकिन निश्चित रूप से java.util.concurrent का उपयोग करने का तरीका है। –

+1

एक बेहतर उत्तर लिखने के लिए स्वतंत्र महसूस करें। –

+2

यदि लाइब्रेरी इंटरप्ट को संभाल नहीं लेती है, तो आप शायद अनंत लूप से कभी भी वापस नहीं आ जाएंगे। । एक तर्क है कि हर जावा प्रोग्रामर करना सीखना चाहिए - :-( –