【问题标题】:Check if external service is running检查外部服务是否正在运行
【发布时间】:2015-06-26 23:15:47
【问题描述】:

我必须检查外部服务是否已启动并正在运行或已挂起。如果外部进程挂起,我必须杀死它并重新启动它。

问题说明:
为了检查进程是否挂起,我尝试调用它。如果挂起,我不会得到任何响应,我会知道服务已挂起。

问题是当我尝试调用进程时,如果它被击中,甚至java线程都会被挂起,所以我想我可以创建一个线程并在该线程中调用进程。

我将在父线程中有一个计数器,如果子线程在一段时间内没有返回,我会杀死它(调用 inturrupt())。

但即便如此,父线程在这里挂起。

我有一个 MyThreadHandler 类如下:

public class MyThreadHandler {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MyThreadHandler myThreadHandler = new MyThreadHandler();
        myThreadHandler.handleThread();
    }

    public void handleThread() {
        System.out.println("STARTING LOOPER THREAD");
        boolean isRunning = false;
        int counter = 0;

        MyThreaad myThread = new MyThreaad();

        if (!isRunning) {
            myThread.start();
            System.out.println("aaaaaaaaaaaaaaaa");
            isRunning = true;
        }
        while (true) {
            System.out.println("while loop");
            counter++;
            if (!myThread.isAlive() || counter == 1000) {
                System.out.println("HUNG THREAD::: Killing thread");
                myThread.interrupt();
                break;
            }
        }
    }
}

我的线程类如下:

public class MyThreaad extends Thread{
    public void run() {
        System.out.println("STARTING LOOPER THREAD");
        MyLooper myLooper = new MyLooper();
        myLooper.loopIndefinite();
    };
}

还有 MyLooper:

public class MyLooper {

    public void loopIndefinite() {
        while (true){
            System.out.println("a");
        }
    }
}

【问题讨论】:

  • Future 是您可能想要的。您可以在超时的情况下致电get。这就是进程挂起的时候。
  • 这篇文章可以帮助你Interrupts
  • 我的意思是这很简单,我创建了一个线程,它应该独立于创建者/父线程执行一些事情。如果我不打算做任何复杂的事情,为什么要使用全线程框架?这是一个简单的场景。我必须检查外部进程是否挂起,我不能直接这样做,因为我当前的线程本身会挂起。我跨越一个子线程并在那里进行处理。如果子线程 id 挂起或在某个时间没有返回。我会对其调用中断,使其退出挂起状态,然后重新启动外部进程....请有人帮忙...
  • 因此,根据 Fildor 提供的链接,我了解只能中断特定方法。我的意思是如果 sleep() 已被调用,它可以被中断。不是因为它正在等待的资源被挂起或不可用而挂起的线程。
  • interrupt() 仅将中断的布尔值设置为 true。如果您的线程不检查此值,它将永远不会停止。由 Runner 线程干净地停止其进程(interrupt() 不是 destroy())

标签: java multithreading


【解决方案1】:

我怀疑问题是两个循环都保持忙碌。在这种情况下,线程调度器可能会长时间执行一个循环,而另一个(父级)则出现挂起。
我猜MyLooper 循环不能更改,因为它模拟了挂起的过程。可以执行以下操作以确保父线程获得一些执行时间:

public void handleThread() {
    System.out.println("STARTING LOOPER THREAD");
    boolean isRunning = false;
    int counter = 0;

    MyThreaad myThread = new MyThreaad();
    myThread.setPriority(Thread.MIN_PRIORITY);  // <=== set priority

    if (!isRunning) {
        myThread.start();
        System.out.println("aaaaaaaaaaaaaaaa");
        isRunning = true;
    }
    while (true) {
        try {
            Thread.sleep(100);                  // <=== sleep
        } catch(InterruptedException e) {
        }
        System.out.println("while loop");
        counter++;
        if (!myThread.isAlive() || counter == 1000) {
            System.out.println("HUNG THREAD::: Killing thread");
            myThread.interrupt();
            break;
        }
    }
}

我添加了 2 行,其中一个用于将“挂起线程”的线程优先级设置为低值,这样即使线程很忙,父线程也可以获得执行时间。第二行是sleep,这样可以确保父线程不会占用所有可用的执行时间。

【讨论】:

    【解决方案2】:

    如果你不检查中断状态,myThread.interrupt() 就不可能做你想做的事。

    你必须在 loopIndefinite 方法中添加以下内容:

    if(Thread.interrupted()) throw new InterruptedException();
    

    你的循环对 CPU 来说是非常激进的,你不应该那样强调 CPU。最好按照 Fildor 的建议使用 ExecutorServices 和 Future。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-04
      • 2021-08-15
      • 2011-05-25
      • 2011-01-20
      • 2018-08-13
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多