如何在java中跟踪和实现嵌套Runnable的取消选项

Posted

技术标签:

【中文标题】如何在java中跟踪和实现嵌套Runnable的取消选项【英文标题】:How to track and implement cancel option for nested Runnable in java 【发布时间】:2019-02-05 05:41:06 【问题描述】:

我正在开发一个使用ZMQ 处理请求的Java 应用程序。我的代码有一些嵌套的Runnable,结构如下:

private class SomeRunnable implements Runnable 
    @Override
    public void run() 
        while (!stop) 
            try 
                createProcess();
            
            catch (Exception e) 
                //handled
            
        
    


public void createProcess()
    ZMsg receivedRequest = receiveReq(); // wait for request
    Runnable workerRunnable = new WorkerRunnable(receivedRequest, this);
    Thread workerThread = new Thread(workerRunnable);
    workerThread.start();

所以每次我使用Fiddler 发送请求时,它都会创建新的WorkerRunnable 并将zmq 请求传递给它以进行进一步处理。 这个 WorkerRunnable 被定义为:

private class WorkerRunnable implements Runnable 
    @Override
    public void run() 
            try 
                // do something with received request
                switch(type) : 
                case EXECUTE:
                    startExecution(); // this will internally create one more thread
                    break;

                case STOP:
                    stopExecution();
                    break;                      
            
            catch (Exception e) 
                //handled
            
        
    

这是非常简单的工作流程:

    我使用fiddler 发出请求以执行某些操作。它将创建一个 WorkerRunnable。

    在下一个请求中,我想停止在步骤 1 中启动的 WorkerRunnable

可能会发生我提出了多个请求,然后我想在其中停止任何一个请求。如何跟踪所有 WorkerRunnable 以及在请求停止它们时如何中断它们? 我尝试了ExecutorService,但没有找到在这种情况下使用它的任何确切方法。请提出正确的方法。

【问题讨论】:

不是一个答案,但是 - 通过在一个线程中生成一个线程,您可以获得什么好处?您是否考虑过上下文切换开销?另外你可能想看看Thread.interupt() @Skynet 在 WorkerRunnable 中,它将在 Java 中进行一些转换,然后对 Python 进行调用,然后它会返回到 java,再次进行一些转换,然后将响应发送回用户。用户还可以发送多个请求,如果请求执行时间过长,用户想要取消特定请求。所以线程产生是我想到的。另外,由于我无法跟踪所有 Runnable,我不知道如何中断特定的 Runnable/Thread。有什么想法吗?? 我确实将线程内的线程视为“红色警报”和糟糕的程序设计。它基于意见,但是,请考虑调试/维护地狱以及您现在所处的情况! :) 对于每个请求,我会在一个线程上从 A 点到 B 点进行设计。 @Skynet 如果您提供一个粗略的设计来回答我的要求,这将很有帮助。 WorkerRunnable 是做什么的?它会更新数据库吗?写入文件?插入队列?它究竟是做什么的?为了还原某些内容,您可能需要有一个映射。 【参考方案1】:

您是否考虑过在您的createProcess() 函数中使用thread pool?如果你使用了一个池,那么你可以提交Callable 任务到池,并取回Future 实例。然后,根据您实现Callable 对象的方式,您可能可以使用Future.cancel() 方法中止任务。

【讨论】:

Future.cancel() 不保证会杀掉。我也试过这个,即使它中断,但我的代码继续执行。 @techie,这就是为什么我说,“取决于你如何实现你的 Callable 对象。”如果任务正在运行,future.cancel(true) 将向工作线程发送一个中断,并将future 标记为已取消,但由您来编写Callable 对象的实现,该对象将注意到中断并停止不管它在做什么。

以上是关于如何在java中跟踪和实现嵌套Runnable的取消选项的主要内容,如果未能解决你的问题,请参考以下文章

Java中Runnable和Thread的区别

Google StackDriver:如何将其他日志与跟踪日志关联(和嵌套)?

Java中Runnable和Thread的区别

如何在python中获取嵌套异常的堆栈跟踪?

如何在嵌套字典中查找所有出现的键,同时跟踪外部字典键值?

Java中Runnable和Thread