与返回值的Java中的并发编程

发布于 2025-02-10 06:07:37 字数 1058 浏览 2 评论 0原文

我在Java中同时编程有问题。我正在研究我的学士学位论文,我必须制作几种方法,这些方法将使我归还一个字符串价值。在期货中,TriggerMessageFututre和GetMetervaluesfuture是一个过程运行,需要在1-5秒之间进行返回字符串值完成后返回。

现在的问题是Future.get()正在阻止我的主线程。我想在我的主线中调用触发器和getMetervalue methode,而不会阻止我的主线程,并在完成后将答案作为返回值。我无法找到解决问题的方法,因为它是没有返回值的解决方案,或者是阻止线程的解决方案。

private String TriggerMessage(String Messagetyp) throws InterruptedException, ExecutionException{
    Future<String> future = new communicator().TriggerMessageFuture(queue,centralSystem,Messagetyp);

    while(!future.isDone()) {
        System.out.println("[TriggerMessage]: Calculating... ");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}

private String getMeterValue(String key) throws Exception{
    Future<String> future = new communicator().getMeterValueFuture(queue,centralSystem,key);

    while(!future.isDone()) {
        System.out.println("[getMeterValue]: Calculating...");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}

I have a problem with concurrent programming in Java. I am working on my bachelor thesis and I have to make several methods which will return me a String value. In the Futures TriggerMessageFututre and getMeterValuesFuture is a process running which takes between 1-5 seconds and returns a String Value when it's finished.

The problem is now that future.get() is blocking my main thread. I want to call the TriggerMessage and the getMeterValue methode in my main without blocking my main thread and get their answer as a return value when they are finished. I wasn't able to find a way to solve my problem, because either it was a solution without return value or it was a solution which blocked the thread.

private String TriggerMessage(String Messagetyp) throws InterruptedException, ExecutionException{
    Future<String> future = new communicator().TriggerMessageFuture(queue,centralSystem,Messagetyp);

    while(!future.isDone()) {
        System.out.println("[TriggerMessage]: Calculating... ");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}

private String getMeterValue(String key) throws Exception{
    Future<String> future = new communicator().getMeterValueFuture(queue,centralSystem,key);

    while(!future.isDone()) {
        System.out.println("[getMeterValue]: Calculating...");
        Thread.sleep(500);
    }

    String result = future.get(); //blocking
    return result;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风念你 2025-02-17 06:07:37

这取决于您指的是哪个主线程,此外,如果您可以使用完整的future s而不是普通的旧java future s。

  1. 使用main(String [] args)线程,

不可能在没有任何形式的阻塞的情况下进行。如果您没有阻止get,则必须在blockingqueue实现上阻止,否则主线程刚刚结束。

  1. 使用Swing Event Dispatch线程,

您需要提交一个连续任务,而future.get是从外部开始的。因此,您要么在任务Future中包含此提交,要么切换到pountableFuture

ExecutorService exec = ...

Future<?> future = exec.submit(() -> {
   var value = someCalculation();
   SwingUtilities.invokeLater(() -> {
       useValueOnEDT(value);
   });
});

CompletableFuture<ValueType> cf = ...

cf.whenComplete((value, error) -> {
    SwingUtilities.invokeLater(() -> {
        if (error != null) {
            handleErrorOnEdt(error);
        } else {
            useValueOnEDT(value);
        }
    });
});
  1. Android Main线程

这个想法与Swing相同,但是您将必须使用处理程序

// given value
new Handler(Looper.getMainLooper()).post(() -> {
    useValueOnMainLooper(value);
});

It depends on what main thread are you referring to, plus if you can use CompletableFutures instead of plain old Java Futures.

  1. Using the main(String[] args) thread

It's not possible to do it without any form of blocking. If you are not blocking on get, you'll have to block on a BlockingQueue implementation, otherwise the main thread just ends.

  1. Using the Swing Event Dispatch thread

You'd need to submit a continuation task which is not possible with Future.get from the outside. So either you include this submission inside the task Future has been created for, or switch to CompletableFuture

ExecutorService exec = ...

Future<?> future = exec.submit(() -> {
   var value = someCalculation();
   SwingUtilities.invokeLater(() -> {
       useValueOnEDT(value);
   });
});

or

CompletableFuture<ValueType> cf = ...

cf.whenComplete((value, error) -> {
    SwingUtilities.invokeLater(() -> {
        if (error != null) {
            handleErrorOnEdt(error);
        } else {
            useValueOnEDT(value);
        }
    });
});
  1. Android Main Thread

The idea is the same as with Swing, but you'll have to use a Handler

// given value
new Handler(Looper.getMainLooper()).post(() -> {
    useValueOnMainLooper(value);
});
爱,才寂寞 2025-02-17 06:07:37

您可以将Future包装到完整的future之类的类似中

static <T> CompletableFuture<T> from(Future<T> future) {
    var delegate = new CompletableFuture<T>();

    CompletableFuture.runAsync(() -> {
        try {
            delegate.complete(future.get());
        } catch (Throwable e) {
            delegate.completeExceptionally(e);
        }
    });

    return delegate;
}

,然后使用该alterableFuture,以异步通过其各种来处理完成。 。当...方法时。

You can wrap the Future into a CompletableFuture like so

static <T> CompletableFuture<T> from(Future<T> future) {
    var delegate = new CompletableFuture<T>();

    CompletableFuture.runAsync(() -> {
        try {
            delegate.complete(future.get());
        } catch (Throwable e) {
            delegate.completeExceptionally(e);
        }
    });

    return delegate;
}

And then use that CompletableFuture to asynchronously handle the completion via its various then... and when... methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文