execute thread periodically and stop it after condition is met or time is over

匆匆过客 提交于 2019-12-11 05:39:03

问题


I want to execute a thread periodically to check if some file is ready for uploaded and upload it as soon as it is ready then stop the thread immediately. Also, if a long time has passed I want to stop the thread regardless the file not being ready, but can't do it inside the run method itself.

    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:


How about using a 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);
    }
}



回答2:


@laughing buddha suggested a watcher. It's probably more resource-efficient than my first suggestion, but I'm not entirely sure it's the right solution in this case, because you're still parking a thread. Nevertheless, I coded a test, and it's short and easy to read, so you may as well have the code:

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;
            }
        }
    }
}


来源:https://stackoverflow.com/questions/44006905/execute-thread-periodically-and-stop-it-after-condition-is-met-or-time-is-over

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!