java - Java 进程的 HealthChecker

标签 java multithreading exception executorservice

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

下面是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 

    }
}

我无法找到暂停所有线程的方法。如果存在数据库异常,我希望所有线程暂停。我正在请求一些建议。

最佳答案

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

1) 主线程中的 while(true) 可能会导致 StackOverflowError。随着 while 循环的每次迭代,您将向执行器添加 10 个以上的线程,并且这将无限地继续下去。

2) run() 中没有循环,因此即使捕获异常并且我们等待 HealthCheck,run() 方法仍然会退出。如果您可以不断地从主线程执行新线程来代替已终止的线程,则 run() 中不需要循环,但该逻辑目前不存在于主循环中。

但是,在这里将这些问题放在一边是阻止工作线程直到发生某些事件(大概是 HealthCheck 全部清除)的一种方法。

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();
        }
    }

}

有几件事值得一提。

1) 主线程仅创建 10 个线程,而不是无限量。您可以根据需要进行调整。

2) Worker 线程是长期存在的,这意味着即使遇到异常(InterruptException 除外),它也会继续运行。

3) HealthCheck 不再是静态对象。相反,它是一个共享对象。

4) HealthCheck 是一个可运行程序,可以在自己的线程中执行以监视错误。我没有添加执行该线程的代码。

5) HealCheck 使用信号量导致线程阻塞,直到错误状态被清除。我寻找了其他可以做到这一点的对象,比如 CountDownLatch 或 CyclicBarrier 或 Phaser,但是这个最接近为我们提供了从一个点阻塞所有线程所需的东西(run() 方法)。

它并不完美,但我认为它让你更接近你想要的。

关于java - Java 进程的 HealthChecker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31941366/

相关文章:

java - 是否可以使用 jsp 变量值来初始化 JQUERY 变量?

java - 如何将节点动态添加到 Oracle ADF 中的 RichTree?

C++ RAII析构函数异常

JavaScript异常处理——显示行号

java - 如何将类中的所有信息存储到单个文本文件中?

java - Switch 语句 - 类型的非法开始、预期的标识符和孤立的大小写?

multithreading - 由于线程化,将值移出闭包

java - Spring Webflux : Extract a value from a Mono and save it into another variable

c++ - C++中的线程程序并不快

java - 为什么未登录异常堆栈跟踪?