2012-08-04 34 views
5

當我第一次使用apache守護進程開發一個用於windows的java服務時,我使用了我非常喜歡的JVM模式。你指定你的類並開始\ stop(靜態)方法。但對於Linux,Jsvc看起來並不像它有相同的選項。我真的很想知道爲什麼?!是否可以從不同的JVM調用java應用程序中的方法?

無論如何,如果我要使用Linux的init系統,我試圖找到一種類似的方式來完成同樣的行爲,無論如何啓動應用程序,但要停止它,我將不得不打電話給方法。

我的問題是,罐子開始後,我該如何使用Java虛擬機庫或其他任何東西,打電話給我的應用程序的方法(將試圖阻止我的應用程序優雅)。

另一側的問題,如果一個應用程序被啓動,並且應用程序有靜態方法,如果我使用java命令行中的一個運行main方法,如果是這樣的應用程序類,以及main方法,這是static會調用另一個靜態方法,我想在其中通知終止信號的類中,是否會在相同的JVM中調用?

回答

8

爲什麼不寧願添加一個ShutdownHook到您的應用程序?

關閉掛鉤只是一個初始化但未啓動的線程。當虛擬機開始其關機序列時,它將以某些未指定的順序啓動所有 註冊的關機掛鉤並讓它們同時運行 。當所有鉤子都完成後,它將運行所有的 未受限制的終結器,如果已啓用終止退出。 最後,虛擬機將停止。請注意,守護進程線程將在關閉序列期間繼續運行,如果通過調用退出方法啓動關閉,非守護進程線程將會繼續運行。

這將使你的罐子被關閉之前正常終止:

public class ShutdownHookDemo { 
    public void start() { 
     System.out.println("Demo"); 
     ShutdownHook shutdownHook = new ShutdownHook(); 
     Runtime.getRuntime().addShutdownHook(shutdownHook); 
    } 

    public static void main(String[] args) { 
     ShutdownHookDemo demo = new ShutdownHookDemo(); 
     demo.start(); 
     try { 
      System.in.read(); 
     } 
     catch(Exception e) { 
     } 
    } 
} 

class ShutdownHook extends Thread { 
    public void run() { 
     System.out.println("Shutting down"); 
     //terminate all other stuff for the application before it exits 
    } 

} 

重要的是要注意

關閉掛接運行時非常重要:

  • 程序正常存在。例如,System.exit()被調用,或者最後一個非守護線程退出。
  • 虛擬機終止。例如CTRL-C。這對應於殺死-SIGTERM pid或者在Unix系統上kill -15 pid。

    • 虛擬機中止
    • 甲SIGKILL信號被髮送到在Unix系統的虛擬機的過程:當

    關閉掛接將不會運行。例如kill -SIGKILL pid或kill -9 pid

  • TerminateProcess調用被髮送到Windows系統上的進程。

或者,如果你必須你可以用它來調用一個類的方法:

public class ReflectionDemo { 

    public void print(String str, int value) { 
    System.out.println(str); 
    System.out.println(value); 
    } 

    public static int getNumber() { return 42; } 

    public static void main(String[] args) throws Exception { 
    Class<?> clazz = ReflectionDemo.class;//class name goes here 
    // static call 
    Method getNumber = clazz.getMethod("getNumber"); 
    int i = (Integer) getNumber.invoke(null /* static */); 
    // instance call 
    Constructor<?> ctor = clazz.getConstructor(); 
    Object instance = ctor.newInstance(); 
    Method print = clazz.getMethod("print", String.class, Integer.TYPE); 
    print.invoke(instance, "Hello, World!", i); 
    } 
} 

和動態加載的類:

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL }, 
    getClass().getClassLoader() 
); 
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader); 
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class); 

參考文獻:

相關問題