2016-03-21 14 views
0

Ich arbeite gerade an einem SSL-Crawler und frage mich, welcher der beste oder sicherste Weg ist, die erzeugten Threads zu beenden. Tatsächlich verzweige ich Threads basierend auf verfügbaren URLs, die aus DB abgerufen werden. Ich habe einen Klassen-Thread-Controller, der alle erstellten Threads überwacht und entscheidet, ob mehr basierend auf der Verfügbarkeit von URLs forciert wird? Ich benötige Ratschläge zum sicheren Töten von Fäden.beste Möglichkeit, Threads in einer Java-Umgebung zu töten?

hier ist der Thread-Controller:

public void startThreadsV4() throws InstantiationException, IllegalAccessException { 
    //creating a pool of maxThreads threads 
    //ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(maxThreads); 
    int m = maxThreads - nThreads; 
    if (availableURLs < m) { 
     m = availableURLs; 
    } 
    System.out.println("Starting "+ m + " threads"); 
    for (int n = 0; n < m; n++) { 
     ControllableThread thread = (ControllableThread) threadClass.newInstance(); 
     thread.setThreadController(this); 
     thread.setMessageReceiver(receiver); 
     thread.setId(nThreads++); 
     thread.setDbhandler(dbhandler); 
     thread.setIOhandler(IOhandler); 
     thread.setIgnoresundomains(ignoresubdomain); 
     thread.start(); 
     allThreads.add(thread); 

    } 
} 

und hier ist die Thread-Logik:

public void run() { 
    ///first thing is to check if the The thread Controller requested 
    IOhandler io = new IOhandler(); 
    try { 
     //Object newTask = dbhandler.getNCURLandMarkTransaction(); 
     Object newTask = dbhandler.getNCURL(); 
     System.out.println("new URL -->"+ newTask); 

     while (newTask != null) { 
      if (tc.getStop() == 1) { 
       return; 
      } else { 
       //treatment in case of ignore sub domains 
       if(ignoresundomains == 1){ 
        String[] temp = new String[2]; 
        temp = io.getHostnamefromURL(newTask.toString()); 
        if(dbhandler.HostExist(temp[0],temp[1])){ 
         return; 
        } 
       } 
       dbhandler.markURLinprogress(newTask.toString()); 
       //notify controler of what we do 
       mr.receiveMessage(newTask, id); 
       //process the new task (URL) 
       System.out.println("Processing" + newTask); 
       process(newTask, tc.getLastrecord(), tc, dbhandler,IOhandler); 
       //dec availabe urls 
       tc.decAvailabeURLs(); 
       dbhandler.markURLcrawled(newTask.toString()); 
       if (tc.getMaxThreads() > tc.getRunningThreads()) { 
        try { 
         tc.startThreadsV4(); 
        } catch (InstantiationException | IllegalAccessException ex) { 
         Logger.getLogger(ControllableThread.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
       //System.out.println("DONE"); 
       //send finished message to controller 
       tc.finished(id); 
       newTask = dbhandler.getNCURL(); 
      } 
     } 
    } catch (SQLException ex) { 
     Logger.getLogger(ControllableThread.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

Antwort

0

Im Grunde, was Sie tun müssen, ist: eine Flagge für Ihren Thread erstellen, und setzen Sie ihn auf falsch. Wann hast du entschieden, dass das der richtige Zeitpunkt ist, um zu töten, setze einfach deine Flagge auf wahr und rufe die join() auf dem Thread auf, den du töten willst.

Dieser Link hat die Lösung besser erklärt. How to properly stop the Thread in Java?

0

Sie stoppen Threads in Java, indem Sie eine explizite Beendigungsbedingung (z. B. boolean, die von einem anderen Thread festgelegt werden kann) implementieren, die auf Ihre Geschäftslogik zugeschnitten ist. Sie überwachen diesen Boolean im Zustand Ihrer While-Schleife und beenden ihn entsprechend. In Ihrem speziellen Fall sehe ich, dass Sie die tc.getStop() verwenden, um etwas Ähnliches zu erreichen. Sie können dies in den Zustand der While-Schleife und & & seine Negation (!(tc.getStop())) zusammen mit den anderen ursprünglichen Zustand verschieben.

Es gibt jedoch keinen anderen sicheren Weg, um die Ausführung der Threads einfach zu beenden, wo auch immer sie sich gerade befindet. Ressourcenlecks können leicht entstehen.

0

Für Stop-Thread empfohlen Verwendung Thread.interrupt() Verfahren und in Code, der in Thread ausgeführt werden Sie Thread.currentThread().isInterrupted() überprüfen und wenn true dann verlassen Schleife und damit aktuellen Thread stoppen.

Aber in Ihrem Fall stoppt Thread, wenn newTask != null. Oder wenn auftreten Ausnahme.

Verwandte Themen