2011-02-13 18 views
5

मैं एक बहु थ्रेडेड वातावरण का उपयोग कर रहा हूं, एक थ्रेड बार-बार scanner.nextLine() पर कॉल करके उपयोगकर्ता इनपुट के लिए सुन रहा है। एप्लिकेशन को समाप्त करने के लिए, यह रनलोप किसी अन्य थ्रेड द्वारा रुक गया है, लेकिन सुनने वाला धागा तब तक नहीं रुक जाएगा जब तक कि अंतिम उपयोगकर्ता इनपुट नहीं किया गया था (nextLine() की अवरुद्ध प्रकृति के कारण)।java.util.Scanner को कैसे बाधित करें अगलीलाइन कॉल

स्ट्रीम बंद करना एक विकल्प नहीं है क्योंकि मैं System.in से पढ़ रहा हूं, जो InputStream लौटाता है जो बंद नहीं है।

क्या स्कैनर को अवरुद्ध करने में कोई रास्ता है, ताकि वह वापस आए?

धन्यवाद

+0

आप 'scanner.nextLine()' के बजाय 'scanner.hasNext()' को कॉल कर सकते हैं, यह विधि ** ** ** javadoc के अनुसार ब्लॉक कर सकता है, इसलिए, आपको इसे संभालने की आवश्यकता हो सकती है। विचार यह है कि 'scanner.nextLine() ',' scanner.hasNext() 'इनपुट को अग्रिम नहीं करता है, इसलिए यदि आप scanner.nextLine को कॉल करने से पहले रीडिंग थ्रेड को किसी अन्य थ्रेड द्वारा रोक दिया गया है तो आप ध्वज की जांच कर सकते हैं () ' –

+1

हां, लेकिन इसमें निरंतर मतदान शामिल होगा। –

+0

आपको सुनने वाले धागे पर Thread.interrupt को कॉल करने में सक्षम होना चाहिए, इससे ioException() विधि से आप एक इंटरप्टेडियोएक्सप्शन प्राप्त कर सकते हैं। यह सुनिश्चित नहीं है कि यह अगलीलाइन() के साथ कैसे इंटरैक्ट करता है या यदि यह आपके अंतर्निहित इनपुटस्ट्रीम के साथ काम करता है, लेकिन इसे अधिकांश मामलों में अगली पंक्ति समाप्त करनी चाहिए। – josefx

उत्तर

8

यह article जब पढ़ने को अवरुद्ध से बचने के लिए एक दृष्टिकोण का वर्णन है। यह कोड स्निपेट देता है, जिसे आप एक टिप्पणी में इंगित करते हुए संशोधित कर सकते हैं।

import java.io.*; 
import java.util.concurrent.Callable; 

public class ConsoleInputReadTask implements Callable<String> { 
    public String call() throws IOException { 
    BufferedReader br = new BufferedReader(
     new InputStreamReader(System.in)); 
    System.out.println("ConsoleInputReadTask run() called."); 
    String input; 
    do { 
     System.out.println("Please type something: "); 
     try { 
     // wait until we have data to complete a readLine() 
     while (!br.ready() /* ADD SHUTDOWN CHECK HERE */) { 
      Thread.sleep(200); 
     } 
     input = br.readLine(); 
     } catch (InterruptedException e) { 
     System.out.println("ConsoleInputReadTask() cancelled"); 
     return null; 
     } 
    } while ("".equals(input)); 
    System.out.println("Thank You for providing input!"); 
    return input; 
    } 
} 

आप या तो इस कोड का उपयोग सीधे, या एक नया closable InputStream वर्ग लिखते हैं, तर्क इस आलेख में वर्णित ऊपर लपेटकर सकता है।

+2

अरे धन्यवाद, मैं ऐसे समाधान की उम्मीद कर रहा था जिसमें सक्रिय प्रतीक्षा शामिल न हो। –

0

निश्चित रूप से। एक नूक का प्रयोग करें। अपने मुख्य धागे के अंत में System.exit(0) पर कॉल करें। यह सब कुछ हत्या करेगा। System.in में सक्रिय थ्रेड भी इंतजार कर रहा है।

समस्या यह है कि System.in अवरुद्ध करने वाला पारंपरिक इनपुट स्ट्रीम है, और जब यह थ्रेड को अवरुद्ध कर रहा है तो इसे चलने के रूप में चिह्नित किया जाता है। आप इसे बाधित नहीं कर सकते हैं। तो System.in को पढ़ने के लिए आप जो भी थ्रेड उपयोग कर रहे हैं वह पढ़ रहा है और पढ़ा धागा को अवरुद्ध कर देगा। आप इन चीजों में से कुछ को चाल के समूह के साथ जोड़ सकते हैं, उन मामलों को छोड़कर पढ़ना छोड़ने से बचें जब हम सुनिश्चित कर सकते हैं कि कोई ब्लॉक नहीं होगा और फिर लगातार मतदान होगा। लेकिन, इस समस्या के आसपास कोई वास्तविक तरीका नहीं है कि पढ़ने के लिए कोई भी प्रयास आपके थ्रेड को लॉक करेगा और अंतर्निहित धाराओं को बंद करने या थ्रेड को रोकने या रोकने से कोई भी आपको बचाएगा। लेकिन, अगर आप पूरे वीएम की हत्या करते हैं ... धागा मर जाएगा।

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

+2

मैंने वास्तव में यह कोशिश की, और 'System.exit (0)' ने आश्चर्यजनक रूप से इसे रोक नहीं दिया। मुझे प्रक्रिया को मारना -9 था। यहां तक ​​कि 'हत्यारा जावा' भी काम नहीं किया। – Arin

+0

यह मेरे लिए काम किया। लेकिन, दुख की बात है कि इस बग/विफलता के साथ मुझे विश्वास होगा कि यह अच्छी तरह से न्यूक प्रतिरक्षा हो सकता है। – Tatarize

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