2017-05-16 4 views
1

Ich möchte regelmäßig einen Thread ausführen, um zu prüfen, ob eine Datei zum Hochladen bereit ist, und sie hochzuladen, sobald sie fertig ist. Wenn eine lange Zeit verstrichen ist, möchte ich den Thread stoppen, obwohl die Datei nicht bereit ist, aber nicht innerhalb der run-Methode selbst.Thread regelmäßig ausführen und stoppen, wenn die Bedingung erfüllt ist oder die Zeit abgelaufen ist

final ScheduledFuture<?> fileUploadedFuture = scheduler.scheduleAtFixedRate(() -> { 
     try { 
      if (fileReady("xyz.txt")) { 
       uploadFile("xyz.txt") 
       //cancel fileUploadedFuture and fileUploadedFutureCanceller 
      } 
     } catch (Exception e) { 
      throw new ServiceException(e); 
     } 
    }, 0, delay, TimeUnit.SECONDS); 

    final ScheduledFuture<?> fileUploadedFutureCanceller = scheduler.schedule(() -> { 
     fileUploadedFuture.cancel(true); 
    }, 60, TimeUnit.SECONDS); 
} 
+1

Sie können watchService in Java verwenden beziehen https://docs.oracle.com/javase/tutorial /essential/io/notification.html –

Antwort

0

Wie wäre es mit einem ScheduledThreadPoolExecutor?

public class TestExecutor { 
    private static ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); 

    private static class PushFile implements Runnable { 
     @Override 
     public void run() { 
      if (new File("test.txt").exists()) { 
       System.out.println("found it!"); 
       exec.shutdown(); 
      } else { 
       System.out.println("waiting"); 
      } 
     } 

    } 

    private static class ShutMeDown implements Runnable { 
     @Override 
     public void run() { 
      System.out.println("timeout"); 
      exec.shutdown(); 
     } 
    } 

    public static void main(String[] args) { 
     exec.scheduleWithFixedDelay(new PushFile(), 0, 1, TimeUnit.SECONDS); 
     exec.scheduleWithFixedDelay(new ShutMeDown(), 10, 1, TimeUnit.SECONDS); 
    } 
} 
+0

Ich denke, ich könnte meinen Scheduler einfach herunterfahren, aber der Scheduler ist nicht lokal und wird für andere Zwecke verwendet, also würde ich nur die richtigen Threads töten und nicht das ganze herunterfahren Ding. – CCC

0

@laughing buddha schlug einen Beobachter vor. Es ist wahrscheinlich ressourceneffizienter als mein erster Vorschlag, aber ich bin mir nicht ganz sicher, ob es in diesem Fall die richtige Lösung ist, weil Sie immer noch einen Thread parken. Trotzdem habe ich einen Test codiert, und es ist kurz und leicht zu lesen, so können Sie auch den Code haben:

public class TestWatchService { 

    public static void main(String[] args) throws IOException, InterruptedException { 
     WatchService watcher = FileSystems.getDefault().newWatchService(); 
     Path file = Paths.get("."); 
     WatchKey key = file.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); 

     List<WatchEvent<?>> events = new ArrayList<>(); 
     for (boolean done = false; ! done; events = key.pollEvents()) { 
      if (events.size()==0) { 
       System.out.println("waiting"); 
       Thread.sleep(2000L); 
      } else { 
       System.out.println("got it!"); 
       done = true; 
      } 
     } 
    } 
} 
+0

Test durch Berühren einer neuen Datei im aktuellen Verzeichnis. Code muss aktualisiert werden, um nach bestimmten Dateinamen etc. zu suchen. –

+0

Danke Jerry, aber ich bin nicht wirklich an dem Dateiteil interessiert. Das war nur ein Beispiel. – CCC

Verwandte Themen