用于Java进程的HealthChecker

用于Java进程的HealthChecker,java,multithreading,exception-handling,executorservice,Java,Multithreading,Exception Handling,Executorservice,我想创建一个健康检查器,它将检查java进程的健康状况。我的流程做了很多事情,而且是多线程的。可能会引发各种异常,如Service/SQL/IO等。我的计划是调用HealthChecker,从catch块检查各个线程中的进程。这将检查所有不同的运行状况,如果出现任何问题,它将暂停线程并适当地记录。将有其他进程通过该进程读取日志,并提醒支持人员采取适当的措施 下面是java进程的一般结构 import java.util.concurrent.ExecutorService; import jav

我想创建一个健康检查器,它将检查java进程的健康状况。我的流程做了很多事情,而且是多线程的。可能会引发各种异常,如Service/SQL/IO等。我的计划是调用
HealthChecker
,从catch块检查各个线程中的进程。这将检查所有不同的运行状况,如果出现任何问题,它将暂停线程并适当地记录。将有其他进程通过该进程读取日志,并提醒支持人员采取适当的措施

下面是java进程的一般结构

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Schedular {
    private static int numOfTasks = 10 ;

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(5);
        while(true){
            for(int i=0;i<numOfTasks;i++){
                service.execute(new Workers());
            }
        }
    }
}

class Workers implements Runnable{
    @Override
    public void run() {
        /*
         * This can throw different exceptions , eg:    
         */
        try{

        }catch(Exception e){
            e.printStackTrace();
            HealthChecker.checkHealth();
        }
    }
}

class HealthChecker{
    public static void checkHealth() {
        //Check health and then , log and pause all the threads 

    }
}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类调度{
私有静态int numotasks=10;
公共静态void main(字符串[]args){
ExecutorService=Executors.newFixedThreadPool(5);
while(true){

对于(int i=0;i,您正在尝试远离最佳实践,但您没有询问监视线程运行状况的最佳实践,因此我不会回答这个问题。相反,我只回答您提出的问题:如何暂停ExecutorService管理的一组线程

假设您的
Workers.run()
最终将在没有干预的情况下结束(换句话说,它不是在一个无限循环中-有意或无意),正确的做法是调用
service.shutdown()
(其中service是ExecutorService的实例)。为此,您可以将服务作为新参数传递到
HealthCheck.HealthCheck()
。调用shutdown()将允许当前运行的线程完成,然后停止执行器

如果
Workers.run()
无法自然完成,最佳做法是您需要更改代码,使其自然完成。您可以调用
Thread.stop()
方法来停止线程和
Thread.suspend()
方法,您可以调用它来挂起线程。这两种方法都是不好的主意,您可以使用它们,原因有两个:

  • 它们已被弃用,将使线程处于超不健康状态。如果使用它们,将来将遇到非常困难的问题
  • 您正在使用ExecutorService。这意味着您正在将线程管理委托给该类。如果您弄乱了ExecutorService下线程的状态,它将无法为您管理线程池,而且,您将来将遇到非常困难的问题

  • 您需要一种方法来阻止线程,直到发生允许线程继续的事件。我发现代码中存在一些主要问题:

    1) 主线程中的
    while(true)
    可能会导致
    StackOverflowerError
    。在while循环的每次迭代中,您将向执行器添加10个线程,这将无限期地继续

    2) 您的run()中没有循环,因此即使捕获到异常并等待HealthCheck,run()方法仍将退出如果您可以不断地从主线程执行新线程,以取代终止的线程,但该逻辑目前不在主循环中

    但将这些问题放在一边是一种阻止工作线程的方法,直到发生某个事件(可能是HealthCheck all clear)为止

    导入java.util.concurrent.ExecutorService;
    导入java.util.concurrent.Executors;
    公共类调度{
    私有静态int numotasks=10;
    公共静态void main(字符串[]args){
    ExecutorService=Executors.newFixedThreadPool(5);
    HealtchChecker hChecker=新的HealthChecker();
    
    对于(int i=0;这不是一个很好的主意。为什么需要暂停所有线程?让代码处理自己的日志记录有什么错?它比您的
    HealthChecker
    类更清楚记录什么。至于跟踪进程和发出警报,您可能需要阅读JMX。这个问题确实需要一些清理。您很简单ng几个不同的问题:1.监控线程运行状况的最佳实践是什么?2.如何监控线程的运行状况?3.如何停止/暂停正在运行的线程?清理问题,使您只问1个问题,将得到更好的答案。为什么会出现
    while(true)
    在主线程中循环?@Kayaman-我们希望所有线程等待问题解决。@Jose Martinez在实际代码中,我将使用布尔变量而不是true。
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Schedular {
        private static int numOfTasks = 10 ;
    
        public static void main(String[] args) {
            ExecutorService service = Executors.newFixedThreadPool(5);
            HealtchChecker hChecker = new HealthChecker();
            for(int i=0;i<numOfTasks;i++){
                service.execute(new Workers(hChecker));
            }
        }
    }
    
    class Workers implements Runnable{
    
        private HealtchChecker hChecker;
    
        public Workers(HealtchChecker hChecker){
            this.hChecker = hChecker;
        }
    
        @Override
        public void run() {
            /*
             * This can throw different exceptions , eg:    
             */
             while(true) {
                try{
    
                }catch (InterruptedException ie) {
                    throw ie;   
                }catch(Exception e){
                    e.printStackTrace();
                    HealthChecker.checkHealth();
                }
             }
        }
    }
    
    class HealthChecker implements Runnable {
    
        private final Semaphore semaphore = new Semaphore(1, true);
    
        public void checkHealth() {
            try {
                semaphore.acquire();
            } finally {
                semaphore.release();
            }
        }
    
        @Override
        public void run(){
            //code to check for errors that cause threads to pause.
            if (inErrorState) {
                semaphore.acquire();
            } else {
                semaphore.release();
            }
        }
    
    }