异步CompletableFuture同步返回到单线程ExecutorService

时间:2017-09-22 01:13:25

标签: multithreading asynchronous java-8 executorservice completable-future

我正在创建单线程ExecutorService 并将任务(CompletableFuture)分配给该单线程服务,该任务需要异步执行(尝试runAsync和supplyAsync)。

package Executor;

import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorResolver {

    ExecutorService es = Executors.newSingleThreadExecutor();
    volatile int counter = 2;
    static int ten = 10;
    static int five = 5;

    public void printer() {

        System.out.println("This thread is complete :" + Thread.currentThread().getName());
        System.out.println(new Date(System.currentTimeMillis()));

    }

    public void execute() {

        CompletableFuture<Void> ct = CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
            try {
                Thread t = new Thread();
                Thread.sleep(ten * 1000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, es).thenRunAsync(this::printer), CompletableFuture.runAsync(() -> {
            try {
                Thread t = new Thread();
                Thread.sleep(five * 1000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, es).thenRunAsync(this::printer)

        );

    }

    public static void main(String args[]) {

        ExecutorResolver er = new ExecutorResolver();

        er.execute();

        for (int i = 0; i < 1000; i++) {
            System.out.println("Current thread name : " + Thread.currentThread().getName() + i);
        }
        System.out.println(new Date(System.currentTimeMillis()));

    }

}

但他们正在同步执行,

See the console log which waits for thread that sleeps for 10 secs and then the executes the one which sleeps for 5 seconds

如果可能或我做错了,请告诉我?

1 个答案:

答案 0 :(得分:0)

我相信你要做的是使用单线程异步编程风格。这种风格在Javascript尤其是node.js应用程序中被大量使用,因为它非常适合必须同时处理许多客户端的服务器端代码,这在this talk中由node.js的创建者进行了很好的解释。然而,在Java世界中,由于某种原因,编程风格并不十分普遍。所以也许你想先学习node.js编程。之后,您可以将您在那里学到的东西翻译成Java。 无论如何,我改变了你的代码,我认为它现在正在做你想要的。问题是您无法通过阻止线程来执行延迟。相反,你也必须使用Future。

package executor;

import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Timer;
import java.util.TimerTask;

public class ExecutorResolver {
    private final ExecutorService es = Executors.newSingleThreadExecutor();
    private static final Timer timer = new Timer();

    public static CompletableFuture<Void> delay(long delay) {
      CompletableFuture<Void> fut = new CompletableFuture<>();
      timer.schedule(new TimerTask() {
        @Override
        public void run() {
          fut.complete(null);
        }
      }, delay);
      return fut;
    }

    public static Date date() {
      return new Date(System.currentTimeMillis());
    }

    public void execute() {
        CompletableFuture<Void> ct = CompletableFuture.allOf(
            CompletableFuture
                .runAsync(() -> {
                    System.out.println(date() + ": started first async operation in thread " + Thread.currentThread());
                }, es)
                .thenComposeAsync(x -> delay(10000), es)
                .thenRunAsync(() -> {
                  System.out.println(date() + ": completed first async operation in thread " + Thread.currentThread());
                }, es)
            ,

            CompletableFuture
                .runAsync(() -> {
                    System.out.println(date() + ": started second async operation in thread " + Thread.currentThread());
                }, es)
                .thenComposeAsync(x -> delay(5000), es)
                .thenRunAsync(() -> {
                  System.out.println(date() + ": completed second async operation in thread " + Thread.currentThread());
                }, es)
          );
    }

    public static void main(String args[]) {
        ExecutorResolver er = new ExecutorResolver();
        er.execute();
    }
}