2017-10-03 7 views
2

J'ai un projet basé sur java 8 qui effectue une certaine fonction sur une URL. J'ai besoin de modifier l'extrait de code ci-dessous afin qu'il soit capable de tuer le thread/processus en cours d'exécution et d'exécuter l'instance suivante après une certaine période de temps indépendamment de l'état actuel du processus.Java 8: Tuer/arrêter un thread après un certain laps de temps

J'ai essayé les techniques suivantes pour mettre en œuvre la procédure de mise à mort de fil:

  • Executor Service
  • minuterie Tâche
  • fil multithread tuer

L'extrait de code pour ma dernière tentative est lié ci-dessous.

@SuppressWarnings("static-access") 
public static void main(String[] args) { 
//fetch url from the txt file 
    List<String> careerUrls = getCareerUrls(); 
    int a = 0; 
    DBConnection ds = null; 
    ds = DBConnection.getInstance(); 
    try (java.sql.Connection con = ds.getConnection()) { 
     //read a single Url 
     for (String url : careerUrls) { 
      int c = a++; 

      ExecutorService executor = Executors.newFixedThreadPool(3); 

      Future<?> future = executor.submit(new Runnable() { 
       @Override 
       // <-- job processing 
       public void run() { 
        long end_time = System.currentTimeMillis() + 10000; 

        System.out.println("STARTED PROCESSING URL: " + url); 
        jobareaDeciderSample w = new jobareaDeciderSample(); 
        w.mainSample(url, c, con); 

       } 
      }); 
      // <-- reject all further submissions 
      executor.shutdown(); 
      try { 
       future.get(120, TimeUnit.SECONDS); // <-- wait 2 Minutes to finish 
      } catch (InterruptedException e) { // <-- possible error cases 
       System.out.println("job was interrupted"); 
       future.cancel(true); 
       Thread.currentThread().interrupt(); 
       ; 
      } catch (ExecutionException e) { 
       System.out.println("caught exception: " + e.getCause()); 
      } catch (TimeoutException e) { 
       System.out.println("timeout"); 
       future.cancel(true); 

      } 

      // wait all unfinished tasks for 2 sec 
      if (!executor.awaitTermination(0, TimeUnit.SECONDS)) { 
       // force them to quit by interrupting 
       executor.shutdownNow(); 
      } 
     } 

    } catch (Exception e) { 
     LOGGER.error(e); 
    } 

} 

Répondre

1

Vous avez raison à votre approche. appelant cancel(true); sur l'avenir est la bonne façon d'arrêter cette tâche.

Vous avez un autre problème: vous ne pouvez pas arrêter un thread. (bien vous pouvez, en utilisant stop() dans la classe thread, mais vous ne devriez jamais le faire).

cancel(true); envoie des informations au thread, qu'il doit être arrêté. Certaines classes Java répondent à cette information et lancent une exception interrompue. Mais certains ne le font pas. Vous devez modifier votre code de tâche, pour vérifier si Thread.currentThread().isInterrupted(), et si c'est le cas, arrêtez l'exécution.

C'est quelque chose que vous avez à faire dans votre code, que vous appelez par

jobareaDeciderSample w = new jobareaDeciderSample(); 
        w.mainSample(url, c, con); 

Vous devriez le faire dans un certain code long spinning temps, si vous avez dit que vous faites des choses avec l'URL, vous devriez faire dans votre boucle while, où vous téléchargez des informations pour le web. En d'autres termes, ne vérifiez que lorsque votre code passe 99% du temps.

Aussi, vous appelez

 Thread.currentThread().interrupt(); 

dans votre thread principal, cela ne fait rien pour vous, comme si vous voulez quitter thread en cours, vous pouvez simplement appeler retourner

+0

Vous devez utiliser 'Discussion .interrupted() 'pour tester l'interruption de votre propre thread si vous voulez y réagir. Cela effacera également le statut. La méthode 'someThreadInstance.isInterrupted()' permet de surveiller l'état, quand vous ne le manipulez pas (peut-être même vous l'appelez depuis un thread différent), donc le statut ne sera pas affecté. – Holger