Java 异步正在阻塞?

标签 java multithreading asynchronous

在Java上做了很多搜索之后,我真的对以下问题感到很困惑:

  1. 为什么我会选择异步方法而不是多线程方法?

  2. Java futures应该是非阻塞的。 非阻塞是什么意思?当从 Future 中提取信息的方法(即 get())是阻塞的并且将简单地暂停整个线程直到该方法处理完了吗?也许是在处理完成时敲响教堂钟声的回调方法?

  3. 如何使方法异步?什么是方法签名?

    public List<T> databaseQuery(String Query, String[] args){
      String preparedQuery = QueryBaker(Query, args);
      List<int> listOfNumbers = DB_Exec(preparedQuery); // time taking task
      return listOfNumbers;
    }
    

    这个虚构的方法如何变成非阻塞方法?或者,如果您需要,请提供一个简单的同步方法及其异步方法版本。

最佳答案

Why would I choose an asynchronous method over a multi-threaded method?

异步方法允许您减少线程数。您可以发出异步调用,然后在它完成时收到通知,而不是在阻塞调用中占用线程。这释放了线程以同时进行其他处理。

编写异步代码可能会更复杂,但好处是提高了性能和内存利用率。

Java futures are supposed to be non-blocking. What does non-blocking mean? Why call it non-blocking when the method to extract information from a Future--i.e., get()--is blocking and will simply halt the entire thread till the method is done processing ? Perhaps a callback method that rings the church bell of completion when processing is complete?

查看 CompletableFuture ,它是在 Java 8 中添加的。它是一个比 Future 更有用的接口(interface)。其一,它允许您将各种回调和转换链接到 future 。您可以设置在未来完成后运行的代码。正如您猜测的那样,这比在 get() 调用中阻塞要好得多。

例如,给定这样的异步读写方法:

CompletableFuture<ByteBuffer> read();
CompletableFuture<Integer> write(ByteBuffer bytes);

您可以像这样从文件中读取并写入套接字:

file.read()
    .thenCompose(bytes -> socket.write(bytes))
    .thenAccept(count -> log.write("Wrote {} bytes to socket.", count)
    .exceptionally(exception -> {
        log.error("Input/output error.", exception);
        return null;
    });

How do I make a method async? What is the method signature?

你会让它返回一个 future 。

public CompletableFuture<List<T>> databaseQuery(String Query, String[] args);

然后该方法负责在其他线程中执行工作并避免阻塞当前线程。有时您会准备好工作线程。如果没有,您可以使用 ForkJoinPool,这使得后台处理变得非常容易。

public CompletableFuture<List<T>> databaseQuery(String query, String[] args) {
    CompletableFuture<List<T>> future = new CompletableFuture<>();
    Executor executor = ForkJoinPool.commonPool();

    executor.execute(() -> {
        String preparedQuery = QueryBaker(Query, args);
        List<T> list = DB_Exec(preparedQuery); // time taking task
        future.complete(list);
    });
}

关于Java 异步正在阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36244951/

相关文章:

java - 如何打印数组列表中的最大数字?

java - 如何配置 apache httpclient 4.5+ SSLContext 以使用带有自签名证书的双向 TLS 身份验证?

java - 如何获取 JDialog 方法?

java - repaint() 不会在调用时重新绘制?

tomcat - 为什么我们不能在Tomcat中使用websocket?

java - 使 Java 类在 Clojure 中作为序列工作

C++ 计算高效且线程安全的随机函数

windows - 线程可以通过自己的线程 ID 调用 SuspendThread 吗?

c++ - asio 异步服务器不接受连接

c# - 使用 C#、.NET 对 Oracle 数据库进行异步数据库操作?