Java 只允许 运行 任务在实例化线程上的执行器模型

Java executor model that allows running tasks only on instantiating thread

我正在编写一个多线程应用程序,在这种情况下,我有某些与库相关的方法可以 运行在 main-thread 上。目前我正在 运行 一个简单的、自写的解决方案,它在队列中侦听任务,然后在任务进入时串行执行它们。

虽然它在我需要 return 值等时变得丑陋,但到目前为止它仍然有效。(我目前正在通过将数据结构与任务一起传递来解决 c-way,然后进行忙循环检查是否该结构已写入任务排队方法的站点。

这并不是最干净的解决方案,虽然它有效,但我希望找到更好的方法..

Q:JDK 或 单一专业化 库中是否有任何东西可以满足我的需要?或者是否有任何编程模式可以以干净和结构化的方式满足我的需求?

CompletableFuture的可能解决方案:

class Job<T> {
    private final Supplier<T> computation;
    private final CompletableFuture<T> future;

    Job(Supplier<T> computation, CompletableFuture<T> future) {
        this.future = future;
        this.computation = computation;
    }

    public Supplier<T> getComputation() {
        return computation;
    }

    public CompletableFuture<T> getFuture() {
        return future;
    }
}

public void client() {
    // on the client:
    CompletableFuture<String> future = new CompletableFuture<>();
    Supplier<String> computation = () -> "Here I am!";

    enqueue(new Job<>(computation, future));

    String resultString = future.get();
}

public <T> void server(Job<T> job) {
    // on the server; job is taken from the queue
    CompletableFuture<T> future = job.getFuture();
    future.complete(job.getComputation().get());
}

此处,在客户端,future.get() 将无限等待直到结果可用。还有一种形式:

future.get(1, TimeUnit.MINUTES)

只会等一分钟然后return。这个for可以用来轮询

让你的主线程扮演执行者的角色:

static ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
public static void main(String... args) {
    // initialization...
    for (;;) {
        queue.take().run();
    }
}

每当您需要在主线程上执行任务时,将其放入队列:

 queue.add(()->methodCall(1,2,3));

我不确定你是如何对主线程进行时间切片的,但你的意思是你想 运行 一些使用多个线程的作业和主线程上的其他作业顺序。

最简单的答案是使用两个不同的工作队列 - 一个由多个线程提供服务,一个仅由主线程提供服务。

这将使两个队列更易于理解和使用。

此外,任一队列上的作业 运行ning 应该实现一个接口,该接口要求它们公开一个方法,该方法 returns 对结果数据的引用 - 这可能是实际结果或文件名称或附加到包含结果的文件的输入流。