2013-04-23 81 views
-1

我想在java中编写一个简单的web服务器,但卡住停止它。下面是一段示例代码:为什么我不能停止这台服务器?

public static void main(String... args) { 

    args = new String[]{"stop"}; 
    Server s = Server.getServerInstance(); 
    s.init(); 
    if (args.length > 0) { 
     for (int i = 0; i < args.length; i++) { 
      if (args[i].equals("start")) { 
        System.out.println(s); 
        s.start(); 
      } else if (args[i].equals("stop")) { 
        System.out.println(s); 
        s.stop(); 
      } 
     } 
    } 
} 

public class Server { 

private static Server serverInstance = null; 
private volatile boolean running = false; 
private Thread serverthread = null; 


private Server() {} 

public static synchronized Server getServerInstance() 
{ 
    if(serverInstance == null) 
    { 
     serverInstance = new Server(); 
    } 
    return serverInstance; 
} 

public void init() 
{ 
    Runnable r = new ServerThread(); 
    serverthread = new Thread(r); 
} 

public void start() 
{ 
    running = true; 
    if(serverthread!=null) 
    { 
     serverthread.start(); 
    } 
} 

public void stop() 
{ 
    running = false; 
    if(serverthread!=null) 
    { 
     try { 
      serverthread.join(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

class ServerThread implements Runnable 
{ 
    @Override 
    public void run() { 
     while(running) 
     { 
      //some action here... 
      System.out.println("RUNNING.."); 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

} 

}

我所有这些代码打包成一个jar文件和使用java命令的* .jar CLASS_NAME ARGS赞扬启动和停止服务器。服务器可以启动,但从未停止传递给停止参数。我调试,发现布尔值运行永远不会改变......为什么?我如何以优雅的方式实现停止方法?谢谢 !!!!

+2

当你运行java第二次,它创建了一个全新的过程中,的。 stop()'调用没有以任何方式连接到第一个进程启动的s。 – Thomas 2013-04-23 02:36:44

+0

为什么'tomcat'? – leonbloy 2013-04-23 02:36:52

+0

你需要一个启动/停止脚本 – 2013-04-23 02:37:58

回答

0

根据您的代码,我会假设您尝试停止的服务器实例不是正在运行的实例。

相反,试试这个。

public static void main(String... args) { 

    Server s = Server.getServerInstance(); 
    s.init(); 
    s.start(); 
    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    s.stop(); 
} 

这将启动您的服务器,等待5秒钟并关闭它。

如果您想要停止在单独进程中运行的服务器,则需要查看使用套接字等内容来启用跨进程通信。

+0

嗨疯了,你是什么意思的独立过程?单独的服务器类实例?我使用单例来确保我会得到相同的实例。谢谢.. – Willie 2013-04-23 03:01:20

+0

如果你要用'start'作为命令行参数运行你的程序(按原样)。它会创建一个进程,在其中创建一个线程即服务器。此过程将只能创建服务器的单个实例。如果使用'start'作为命令行参数再次运行它,它将使用作为服务器的新线程创建一个新进程。这就是为什么你无法阻止它。每次运行该程序时,它都会创建一个单独的进程,该进程不知道您创建的所有其他进程/线程 – MadProgrammer 2013-04-23 03:04:55

+0

感谢Mad,您的解释使场景变得更好,并且您有任何建议或想法可以阻止已启动的服务器通过命令?我想用java命令“java -cp JAR_FILES BOOTSTRAP_CLASS_NAME args”使用shell脚本,这里的参数将是[start,stop,status]。 – Willie 2013-04-23 03:22:17

0

我建议你用那样的脚本(当然,如果你的Java服务器运行Linux)

#!/bin/sh 

PROGRAM_NAME=servername 
PROGRAM_HOME=/usr/local/servername 
PIDFILE=/var/run/$PROGRAM_NAME.pid 

application_start() { 
    CMDLINE="/usr/lib/java/bin/java -jar $PROGRAM_NAME.jar" 
    echo -n "Starting $PROGRAM_NAME daemon: $CMDLINE" 
    cd $PROGRAM_HOME 

    /usr/lib/java/bin/java -classpath lib -jar $PROGRAM_NAME.jar & 
    ps -Ao pid,command | grep java | grep $PROGRAM_NAME.jar | awk '{print $1}' > $PIDFILE 
    echo 
} 

application_stop() { 
     echo -n "Stopping $PROGRAM_NAME daemon..." 

     if [ -r $PIDFILE ]; then 
       PID=`cat $PIDFILE` 
       if [ $PID -gt 0 ]; then 
         kill $PID 
         echo 
         sleep 1 
         fi 
       rm -f $PIDFILE 
     fi 
     killall $PROGRAM_NAME 
} 

application_restart() { 
    application_stop 
    sleep 1 
    application_start 
} 

case "$1" in 
'start') 
    application_start 
    ;; 
'stop') 
    application_stop 
    ;; 
'restart') 
    application_restart 
    ;; 
*) 
    echo "usage $0 start|stop|restart" 
esac 
+0

谢谢亚历克斯,请允许我以这种方式给你打电话..我完全理解我可以使用shell脚本,我之前使用过这种方式,但是简单地杀死这个进程并不是一个好方法来阻止服务器。所有的服务突然死亡可能会导致数据损坏或什么..“不是一个优雅的方式来停止服务器..” - 我看到这本书中的报价<如何tomcat工程..> :)但仍然谢谢你.. – Willie 2013-04-23 02:53:36

+0

另一个更好也许,赶上杀死信号:http://stackoverflow.com/questions/2541597/how-to-gracefully-handle-the-sigkill-signal-in-java – 2013-04-23 03:15:03

+0

谢谢亚历克斯..我还有很多要学习你们.. :) – Willie 2013-04-23 03:18:17