java_shixisheng 2019-01-28 15:16 采纳率: 0%
浏览 522

并发编程框架Disruptor,执行shutdown就会卡死。

在使用并发编程框架Disruptor,执行shutdown就会卡死。

 public synchronized  void authNewPersonalByRotmote() {
        if (flag) return;
        flag = true;
        log.info("获取待远程验证的身份证记录");
        NewDisruptorPublisher publisher= NewDisruptorPublisher.getNewPersonalInstance();
        try {
            List<PersonalInfo> list = personalInfoDao.getPersonalByAllWaitAuth();
            if (list.size() < 1) {
                flag = false;
                return;
            }
            //按照姓名身份证号 逐条远程验证获取回执
            for (PersonalInfo info : list) {
                publisher.publish(new NewPersonalEventArgs(info));
            }
        } catch (Exception ex) {
            log.error("身份证验证发生错误", ex);
            return;
        }finally {
            publisher.shutdown();
            flag = false;
        }
    }

如果执行disruptorNewPersonal.shutdown();程序就被卡死、如果不执行Handler中的事件正常执行

 public void shutdown() {
        if (personalFlag) {
           disruptorPersonal.shutdown();
            personalFlag = false;
        }
        if (personalNewFlag) {
           disruptorNewPersonal.shutdown();
           personalNewFlag = false;
        }
        //   disruptorEntry.shutdown();
        if (entryFlag) {
            disruptorEntry.shutdown();
            entryFlag = false;
        }
        if (fileFlag) {
            disruptorFile.shutdown();
            fileFlag = false;
        }
    }
  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-07 19:43
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    Disruptor 是一个用于处理大量异步事件的应用程序框架。它允许您编写和调试高性能的并发应用程序。

    关于 disruptorNewPersonal.shutdown();shutdown() 方法的问题:

    当您尝试调用 disruptorNewPersonal.shutdown(); 时,可能会导致 shutdown() 方法在运行时被中断。这是因为 disruptorNewPersonal.shutdown() 方法会调用 shutdown() 方法,然后 shutdown() 方法又会调用 shutdownNow() 方法,这将导致 disruptorNewPersonal.shutdown() 的调用立即失败并抛出异常。

    要解决此问题,请确保在调用 disruptorNewPersonal.shutdown(); 后等待所有事件都被处理完毕再进行其他操作。例如:

    private boolean isShutdownComplete = false;
    
    public void shutdown() {
        while (!isShutdownComplete) {
            try {
                // 等待所有事件处理完毕
                // ...
                // ... 
            } catch (InterruptedException e) {
                // 处理中断异常
                Thread.currentThread().interrupt();
            }
    
            // 调用 shutdownNow()
            disruptorNewPersonal.shutdownNow();
        }
    
        isShutdownComplete = true;
    }
    

    这样可以确保所有事件都已被处理完毕后,shutdown() 方法才能继续往下执行。

    另外,在某些情况下,您可能需要考虑使用 disruptorNewPersonal.shutdown();shutdown() 方法之间的延迟。例如,您可以添加一个线程睡眠来确保所有事件都已处理完毕后再调用 shutdown() 方法。这可以通过以下方式实现:

    public void shutdown() {
        final CountDownLatch latch = new CountDownLatch(1);
    
        Runnable shutdownTask = () -> {
            try {
                latch.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
    
            try {
                disruptorNewPersonal.shutdown();
            } catch (Throwable t) {
                // 处理任何可能发生的问题
            }
    
            try {
                disruptorNewPersonal.shutdownNow();
            } catch (Throwable t) {
                // 处理任何可能发生的问题
            }
    
            try {
                disruptorNewPersonal.shutdownNow();
            } catch (Throwable t) {
                // 处理任何可能发生的问题
            }
    
            // 在这里添加您的其他操作
    
            latch.countDown();
        };
    
        new Thread(shutdownTask).start();
    
        // 确保所有事件处理完毕
        try {
            latch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    

    通过这种方式,您可以在调用 shutdown() 方法之前确保所有事件都已经处理完毕。

    评论

报告相同问题?