Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 无响应的参与者系统:ThreadPoolExecutor dispatcher只创建核心线程池,显然忽略了最大线程池大小_Java_Multithreading_Scala_Akka_Blocking - Fatal编程技术网

Java 无响应的参与者系统:ThreadPoolExecutor dispatcher只创建核心线程池,显然忽略了最大线程池大小

Java 无响应的参与者系统:ThreadPoolExecutor dispatcher只创建核心线程池,显然忽略了最大线程池大小,java,multithreading,scala,akka,blocking,Java,Multithreading,Scala,Akka,Blocking,更新:我发现,如果我将ThreadPoolExecutor的核心池大小设置为与最大池大小(29个线程)相同,我的程序将保持响应。但是,如果我将核心池大小设置为11,将最大池大小设置为29,那么actor系统只创建11个线程。如何配置ActorSystem/ThreadPoolExecutor继续创建线程以超过核心线程数并保持在最大线程数内?我不希望将核心线程数设置为最大线程数,因为我只需要额外的线程来取消作业(这应该是一个罕见的事件) 我有一个针对Oracle数据库运行的批处理程序,使用Jav

更新:我发现,如果我将
ThreadPoolExecutor的
核心池大小设置为与最大池大小(29个线程)相同,我的程序将保持响应。但是,如果我将核心池大小设置为11,将最大池大小设置为29,那么actor系统只创建11个线程。如何配置ActorSystem/
ThreadPoolExecutor
继续创建线程以超过核心线程数并保持在最大线程数内?我不希望将核心线程数设置为最大线程数,因为我只需要额外的线程来取消作业(这应该是一个罕见的事件)


我有一个针对Oracle数据库运行的批处理程序,使用Java/Akka类型的参与者和以下参与者实现:

  • BatchManager
    负责与REST控制器对话。它管理未初始化的批处理作业的
    队列
    ;当从队列轮询未初始化的批处理作业时,它将变为
    JobManager
    actor并执行
  • JobManager
    维护一个存储过程队列和一个
    工作者池
    ;它用一个存储过程初始化每个
    工作者
    ,当
    工作者
    完成时,它将过程的结果发送给
    作业管理器
    ,而
    作业管理器
    将另一个存储过程发送给
    工作者
    。当作业队列为空且所有
    worker
    空闲时,批处理终止,
    JobManager
    将其结果报告给
    BatchManager
    ,关闭其worker(通过
    TypedActor.context().stop()
    ),然后关闭自身。
    JobManager
    具有一个
    承诺完成
    ,当作业成功完成时,或者当作业因取消或致命异常而终止时,该承诺完成
  • Worker
    执行存储过程。它创建用于执行存储过程的和,并向
    JobManager.completion
    注册
    onFailure
    回调以
    abort
    连接和
    cancel
    语句。此回调不使用actor系统的执行上下文,而是使用从
    BatchManager
    中创建的缓存执行器服务创建的执行上下文
  • 我的配置是

    {"akka" : { "actor" : { "default-dispatcher" : {
        "type" : "Dispatcher",
        "executor" : "default-executor",
        "throughput" : "1",
        "default-executor" : { "fallback" : "thread-pool-executor" }
        "thread-pool-executor" : {
            "keep-alive-time" : "60s",
            "core-pool-size-min" : coreActorCount,
            "core-pool-size-max" : coreActorCount,
            "max-pool-size-min" : maxActorCount,
            "max-pool-size-max" : maxActorCount,
            "task-queue-size" : "-1",
            "task-queue-type" : "linked",
            "allow-core-timeout" : "on"
    }}}}}
    
    工人数量在别处配置,目前
    workerCount=8
    coreActorCount
    workerCount+3
    maxActorCount
    workerCount*3+5
    。我正在一台有两个内核和8GB内存的MacBookPro 10上进行测试;生产服务器要大得多。我正在谈论的数据库是在一个非常慢的VPN后面。我使用Oracle的JavaSE 1.8 JVM运行所有这些。本地服务器是Tomcat7。Oracle JDBC驱动程序的版本是10.2(我可能能够说服那些使用更新版本的超级用户)。所有方法要么返回
    void
    要么返回
    Future
    并且应该是非阻塞的

    当一个批次成功终止时,则没有问题-下一个批次立即开始,并有完整的工人。但是,如果我通过
    JobManager#completion.tryFailure(新取消异常(“批取消”))
    终止当前批处理,则
    工作人员注册的
    onFailure
    回调将触发,然后系统将变得无响应。Debug PRINTLN表明新批处理从八分之三的正常工作人员开始,并且
    BatchManager
    变得完全无响应(我添加了一个
    Future ping
    命令,该命令只返回一个
    Futures.successful(“ping”)
    ,这也会超时)。
    onFailure
    回调在一个单独的线程池上执行,即使它们在actor系统的线程池上,我也应该有足够高的
    最大池大小
    ,以容纳原始的
    JobManager
    、其
    工作人员
    、其
    onFailure
    回调,第二个是
    JobManager
    ,是
    Workers
    。相反,我似乎在适应原来的
    JobManager
    及其
    工作人员
    ,新的
    JobManager
    及其不到一半的
    工作人员
    ,而
    BatchManager没有剩余的东西。
    我运行此功能的计算机资源不足,但它似乎应该能够运行十几个线程

    这是配置问题吗?这是由于JVM施加的限制和/或Tomcat施加的限制造成的吗?这是因为我如何处理阻塞IO的问题吗?我可能还有其他几件事做错了,这些正是我想到的

    其中,
    CallableStatement
    OracleConnection
    被取消

    其中创建了
    cancelablestatements

    通过
    System.out.println(mergedConfig.toString())获取


    编辑:我相信我已经将问题缩小到了actor系统(它的配置或与阻止数据库调用的交互)。我消除了
    工作者
    参与者,并将他们的工作负载移动到在固定大小的
    ThreadPoolExecutor
    上执行的
    Runnables
    ,其中每个
    JobManager
    创建自己的
    ThreadPoolExecutor
    ,并在批处理完成时关闭它(
    正常终止时关闭
    ,异常终止时关闭
    ).Cancellation在
    BatchManager
    中实例化的缓存线程池上运行。actor系统的dispatcher仍然是
    ThreadPoolExecutor
    ,但只有六个线程分配给它。使用此替代设置,Cancellation按预期执行-w
    PerformanceAsync-akka.actor.default-dispatcher-19
      at java.net.SocketInputStream.socketRead0(Ljava/io/FileDescriptor;[BIII)I (Native Method)
      at java.net.SocketInputStream.read([BIII)I (SocketInputStream.java:150)
      at java.net.SocketInputStream.read([BII)I (SocketInputStream.java:121)
      at oracle.net.ns.Packet.receive()V (Unknown Source)
      at oracle.net.ns.DataPacket.receive()V (Unknown Source)
      at oracle.net.ns.NetInputStream.getNextPacket()V (Unknown Source)
      at oracle.net.ns.NetInputStream.read([BII)I (Unknown Source)
      at oracle.net.ns.NetInputStream.read([B)I (Unknown Source)
      at oracle.net.ns.NetInputStream.read()I (Unknown Source)
      at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1()S (T4CMAREngine.java:1109)
      at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1()B (T4CMAREngine.java:1080)
      at oracle.jdbc.driver.T4C8Oall.receive()V (T4C8Oall.java:485)
      at oracle.jdbc.driver.T4CCallableStatement.doOall8(ZZZZ)V (T4CCallableStatement.java:218)
      at oracle.jdbc.driver.T4CCallableStatement.executeForRows(Z)V (T4CCallableStatement.java:971)
      at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout()V (OracleStatement.java:1192)
      at oracle.jdbc.driver.OraclePreparedStatement.executeInternal()I (OraclePreparedStatement.java:3415)
      at oracle.jdbc.driver.OraclePreparedStatement.execute()Z (OraclePreparedStatement.java:3521)
      at oracle.jdbc.driver.OracleCallableStatement.execute()Z (OracleCallableStatement.java:4612)
      at com.util.CPProcExecutor.execute(Loracle/jdbc/OracleConnection;Ljava/sql/CallableStatement;Lcom/controller/BaseJobRequest;)V (CPProcExecutor.java:57)
    
    SELECT s1.username || '@' || s1.machine
        || ' ( SID=' || s1.sid || ' )  is blocking '
        || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status
        FROM v$lock l1, v$session s1, v$lock l2, v$session s2
        WHERE s1.sid=l1.sid AND s2.sid=l2.sid
        AND l1.BLOCK=1 AND l2.request > 0
        AND l1.id1 = l2.id1
        AND l1.id2 = l2.id2
    
      "task-queue-size": "-1",
      "task-queue-type": "linked"