Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现异步计算?_Java_Multithreading_Asynchronous - Fatal编程技术网

Java 如何实现异步计算?

Java 如何实现异步计算?,java,multithreading,asynchronous,Java,Multithreading,Asynchronous,我一直在考虑用Java实现异步处理的不同方法。我想到了一些可能性,想听听你对其中一些是否比另一些好的看法,也许还能得到进一步的建议。想到的最常见的用例是使用以下APIvoid sendData(数据数据)或甚至void sendData(数据数据数据,处理程序)通过连接(例如TCP)发送数据包。以下是我的一些想法: 专用数据发送循环—有一个didicated线程,其行为有点像Java中的事件调度线程,所有其他线程都会调用并提交请求。这些请求存储在一个队列中,并定期清空queu并发送所有请求 使用

我一直在考虑用Java实现异步处理的不同方法。我想到了一些可能性,想听听你对其中一些是否比另一些好的看法,也许还能得到进一步的建议。想到的最常见的用例是使用以下API
void sendData(数据数据)
或甚至
void sendData(数据数据数据,处理程序)
通过连接(例如TCP)发送数据包。以下是我的一些想法:

  • 专用数据发送循环—有一个didicated线程,其行为有点像Java中的事件调度线程,所有其他线程都会调用并提交请求。这些请求存储在一个队列中,并定期清空queu并发送所有请求
  • 使用后台线程排空队列-连接可以维护挂起请求的列表,并使用后台线程排空队列(进行一些同步)
  • Executor service—将请求传递给服务并从后台线程调用处理程序
  • 异步通道-最高级的方法,委托给实现

  • 这些建议中有哪一个更适合使用,或者如果您有其他的一般想法,请分享您的意见。

    您的大多数建议实际上是对同一事物的不同修饰方式

    在幕后,executor服务有一个由1个或多个后台线程组成的池,用于排空队列。向它提交请求

    1和2都是“将要做的事情排队,让一个线程来处理它”的说法

    所以基本上1和2都是彼此的变体。它们也是3的子集

    四个人。我不知道你在这里是什么意思

    ExecutorService
    的设计目的正是为了完成您正试图完成的任务-如果您有多个线程来执行任务,那么这显然是执行任务的方法


    如果只有一个线程,您仍然可以使用
    ExecutorService
    ,但选择不太明确。只要使用一个线程和一个
    阻塞队列
    就相当简单了,所以这可能是一个可行的方法。

    我总是使用一个executor服务来实现并发。它们的级别足够高,可以隐藏管理线程的复杂性并允许线程重用。您可以将任务提交给executor,executor将有效地充当队列,或者让许多任务使用同步队列(如阻塞队列)来共享数据。后者可能允许更大的灵活性,例如,对队列项目进行批处理


    我还强烈推荐Guava,因为它可以解决处理并发时可能遇到的许多问题。

    您应该清楚地将异步管道设计为具有数据/事件依赖关系的图形。典型图由两种节点组成:

    fast handler:
         immediately invoked when an event happens and:
         probably stores the event,
         and/or calls another fast handler,
         and/or submits an asynchronous task to an executor
    
    task:
         runs and issues events (that is, calls fast handlers)
    
    因此,基本上您需要开发两个独立的层:快速处理程序和任务执行器。执行器是通用的,可以从java.util.concurrent包中获取。快速处理程序在很大程度上依赖于您的问题域,并且没有适用于所有情况的通用库。例如,纯队列是一个只存储事件的快速处理程序,因此几乎没有用处

    如果使用I/O,则需要使用标准I/O库,以便它们为处理程序发出I/O事件。它可以使用线程进行同步I/O构建,也可以使用选择器线程或异步通道进行异步I/O构建

    NIO2异步通道使用的快速处理程序示例:

     class ConnectionAcceptor  implements CompletionHandler<AsynchronousSocketChannel, Void>{
       AsynchronousServerSocketChannel assc;
       int maxConn;// max number of simultaneous connections
       int connCount=0;
    
       /* called on creation to start listening incoming client connection requests */
       void allowAccept() {
           assc.accept(null, this);
       }
    
       /* called by I/O layer when a client connection requested */
       public synchronized void completed(AsynchronousSocketChannel result, Void attachment) {
          executor.exec(new Connection(result));
          connCount++;
          if (connCount<maxConn) {
            allowAccept();
          }
       }
    
       /* called by Connection when it is closed */
       synchronized void connClosed() {
          if (connCount==maxConn) {
            allowAccept();
          }
          connCount--;
       }
    }
    
    类ConnectionAcceptor实现CompletionHandler{
    异步服务器socketchannel assc;
    int maxConn;//同时连接的最大数量
    int connCount=0;
    /*在创建时调用以开始侦听传入的客户端连接请求*/
    void allowAccept(){
    关联接受(空,此);
    }
    /*请求客户端连接时由I/O层调用*/
    已完成公共同步作废(AsynchronousSocketChannel结果,作废附件){
    executor.exec(新连接(结果));
    connCount++;
    if(connCount):可取消的异步计算