2016-08-02 8 views
0

Ich versuche, ein Programm zu machen, das ein Vokabular aus einer Datei .txt erstellt. Es nimmt eine Datei, erstellt ein Dokument (eine Zeichenkette), teilt dieses Dokument in Sätze auf und schließlich führt es für jeden Satz eine Operation durch (Tokenisierung, Pos-Tagging, Syntaxanalyse von Costitenten usw.).Zum nächsten Index in einer for-Schleife mit Thread nach einer bestimmten Zeit

Irgendwann stoppt das Programm auf einen Satz (das ist schlecht für mich), also was ich tun würde, ist zu vermeiden, auf einem Satz zu bleiben Zeit (nehmen wir an, 120s). Wenn ja, sollte das Programm zum nächsten Satz in der Liste gehen.

Ich dachte, einen Thread und einen Timer zu verwenden und zu überprüfen, ob diese Zeit verstrichen ist, aber ich bin verwirrt, wie man den Thread benutzt.

Hier ist ein Teil meines Codes:

public class Vocabulary { 
    private Thread thread; 
    private long sentenceDuration; 
    private Queue<File> corpus; 

    public Vocabulary(){ 
     this.sentenceDuration = 0;   
     corpus = loadCorpus(); 
    } 

    public void buildVocabulary(){ 

     for (File f : corpus) { 
       Scanner in = new Scanner(new FileReader(f.getPath())); 

       // Create a string representing the document 
       String document = ""; 
       while (in.hasNextLine()) { 
        document += in.nextLine() + " "; 
       } 
       in.close(); 

       // Split the document in sentences 
       ArrayList<String> sentences = tpr.documentToSentences(document); 

       for (int i = 0; i < sentences.size(); i++) { 
        Timer timer = new Timer(1000, timer()); 
        timer.start(); 

        while(sentenceDuration < 120){  // while it takes under 120 seconds to compute the sentence, ok. 

         List<CoreLabel> tokens = tpr.tokenize(sentences.get(i));  // tokenize the sentence 
         Tree parse = tpr.apply(tokens);         // create the costituents tree 
         Object[] basicDependencies = tpr.getBasicDependencies(parse); // get the basic dependencies from the tree 

         // some operations here...    

         Thread.sleep(1000);  // 1000 ms 
        } 

        // when it takes over 120 seconds to compute the sentence, jump to the next sentence 
        System.out.println("Hey, I took long time to compute the sentence. I'm going to the next one!"); 
       } 

       // Other operations here... 
     } 
    } 

    public void start() { 
     end(); 
     this.thread = new Thread(this); 
     this.thread.start(); 
    } 

    public void end() { 
     if (thread != null && thread.isAlive()) { 
      thread.interrupt(); 
     } 
    } 

    private ActionListener timer() { 

     ActionListener taskPerformer = new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       sentenceDuration++; 
      } 
     }; 
     return taskPerformer 
    } 
} 

Im Haupt nenne ich einfach:

public static void main(String[] args) { 
     new Vocabulary().start();  
} 

Wie kann ich auf das Programm sagen: „wenn 120s übergeben werden, den Satz überspringen“ . Das heißt, "verlassen Sie die While-Schleife sofort! Egal, welche Operation Sie gerade machen." ?

Vielen Dank!

Antwort

1

OK kratzt so die Semaphore, ein Einfache Join() wird tun. Etwas wie:

// Split the document in sentences 
ArrayList<String> sentences = tpr.documentToSentences(document); 

for (int i = 0; i < sentences.size(); i++) { 
    SentenceProcessorThread sentenceProcessorThread = new SentenceProcessorThread(sentences.get(i)); 
    sentenceProcessorThread.start(); 
    try { 
     sentenceProcessorThread.join(120000); // your timeout period goes here 
     if (sentenceProcessorThread.isAlive()) { 
      sentenceProcessorThread.interrupt(); 
      System.out.println("aborting thread"); 
     } 
    } catch (InterruptedException x) { 
    } 
} 

Werfen Sie Ihre Satz Verarbeitungslogik in einem eigenen Thread:

class SentenceProcessorThread extends Thread { 
    private String sentence; 

    public SentenceProcessorThread(String sentence) { 
     this.sentence = sentence; 
    } 

    public void run() { 
     try { 
      // your sentence processing logic goes here 
     } catch (InterruptedException x) { 
     } 
    } 
} 
+0

Danke .. das ist die Art und Weise, die ich nehme. Aber kann ich dich bitten, mir ein Beispiel zu geben, das deine Antwort erweitert? Ich habe Semaphoren nie benutzt. –

+0

Ich werde meine Antwort aktualisieren, wenn ich zu einer IDE komme, damit ich Ihnen ein funktionierendes Beispiel geben kann – SpaceghostAli

+0

Wie ich verstanden habe, dient tryAcquire dazu, eine resocurce zu erwerben, und so tryAcquire (120) einfach 120 s warten, bevor die Anfrage geht. join() ist wahrscheinlich, was ich brauche ... der Thread muss seine Operationen ausführen, und wenn 120 verstrichen ist, muss er sterben! Ihre Antwort ist einfach und prägnant. Vielen Dank! –

0

Die einfachste und weniger fehleranfällig Art und Weise ist es, die Anfangszeit in einer Variablen zu halten und regelmäßig in Ihrem Code überprüfen, ob mehr als 120 Sekunden als nächstes vergangen sind:

for (int i = 0; i < sentences.size(); i++) { 
    // initial time 
    long initialTime = System.currentTimeMillis(); 

    List<CoreLabel> tokens = tpr.tokenize(sentences.get(i)); 
    // Check if more than 120 sec have elapased 
    if (System.currentTimeMillis() - initialTime > 120_000L) { 
     System.out.println(
      "Hey, It took long time to compute the sentence. I'm going to the next one!" 
     ); 
     continue; 
    } 
    ... 
+0

Es wäre sinnvoll, die if-Anweisung innerhalb einer inneren Schleife zu setzen. (Ich bin nicht der Downvoter) – ciamej

+0

das Problem ist, dass ich nicht weiß, wo genau es lange dauern wird, um eine Operation zu tun (kann die Tokenization sein, oder die Pos-Tagging etc.) Also sollte ich in der Lage sein zu ändern aktueller Index zum nächsten, unter Vermeidung anderer Anweisungen in der für –

+0

Sie könnten z Fügen Sie eine innere Schleife nach tokenize hinzu, die für jedes Token etwas tun würde, und die Überprüfung würde n-mal statt nur einmal für die äußere Schleifeniteration durchgeführt werden. – ciamej

Verwandte Themen