Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package io.github.staakk;
- import java.util.Optional;
- import java.util.concurrent.ConcurrentLinkedQueue;
- import java.util.function.Consumer;
- import java.util.function.Supplier;
- public class Main {
- private Worker worker = new Worker();
- public static void main(String[] args) {
- Worker w = new Main().worker;
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- System.out.println("Shutting down gracefully");
- w.halt();
- }));
- w.start();
- Task t1 = Task.from(() -> {
- });
- w.schedule(t1);
- trySleep(2000);
- w.schedule(t1);
- while (true) {
- }
- }
- private static void trySleep(long ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- // ignore
- }
- }
- }
- class Worker extends Thread {
- private volatile boolean running = true;
- private final ConcurrentLinkedQueue<Task> tasks = new ConcurrentLinkedQueue<>();
- @Override
- public void run() {
- System.out.println("Worker started");
- while (running) {
- Optional.ofNullable(tasks.poll())
- .ifPresent(Task::execute);
- if (tasks.isEmpty()) {
- try {
- System.out.println("Worker waiting");
- synchronized (this) {
- wait();
- }
- } catch (InterruptedException e) {
- System.out.println("Worker notified");
- }
- }
- }
- System.out.println("Worker stopped");
- }
- public void schedule(Task t) {
- tasks.add(t);
- synchronized (this) {
- notify();
- }
- }
- public void halt() {
- running = false;
- synchronized (this) {
- notify();
- try {
- join();
- } catch (InterruptedException e) {
- // ignored
- }
- }
- }
- }
- class Task<R> {
- private final Supplier<R> f;
- private final Consumer<R> r;
- private final Consumer<Exception> e;
- public static <R> Task<R> from(Supplier<R> f, Consumer<R> r, Consumer<Exception> e) {
- return new Task<>(f, r, e);
- }
- public static <R> Task<R> from(Supplier<R> f, Consumer<R> r) {
- return from(f, r, Exception::printStackTrace);
- }
- public static Task<Void> from(Runnable f) {
- return from(
- () -> {
- f.run();
- return null;
- },
- v -> {
- },
- Exception::printStackTrace);
- }
- private Task(Supplier<R> f, Consumer<R> r, Consumer<Exception> e) {
- this.f = f;
- this.r = r;
- this.e = e;
- }
- public void execute() {
- try {
- r.accept(f.get());
- } catch (Exception e) {
- this.e.accept(e);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement