【问题标题】:Java executor model that allows running tasks only on instantiating threadJava 执行器模型,只允许在实例化线程上运行任务
【发布时间】:2017-06-04 11:11:32
【问题描述】:

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

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

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

:JDK 或单个专业 库中是否有任何东西可以满足我的需求?或者是否有任何编程模式能够以简洁和结构化的方式满足我的需求?

【问题讨论】:

  • 为什么不直接将未来添加到您现有的架构中?传递 CompletableFuture 而不是与投票相关的结构。然后客户端可以使用get() 方法等待(或轮询)它。
  • @RomanPuchkovskiy 我想我不知道从哪里开始实施未来的机制。也许我想得太远了.....除非我只是有一个绝妙的主意,即简单地使用信号量作为 get 方法的一种等待锁定:/
  • 在建议的方法中添加了插图

标签: java multithreading task scheduling


【解决方案1】:

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)

只会等待一分钟然后返回。这个for可以用于轮询。

【讨论】:

  • 这太疯狂了。我实际上没有意识到有实现的期货。只见过界面。
【解决方案2】:

让你的主线程扮演一个Executor的角色:

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

当你需要在主线程上执行一个任务时,把它放到队列中:

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-08-31
      • 2011-12-14
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      相关资源
      最近更新 更多