为什么我不能停止这台服务器?
我想在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赞扬启动和停止服务器。服务器可以启动,但从未停止传递给停止参数。我调试,发现布尔值运行永远不会改变......为什么?我如何以优雅的方式实现停止方法?谢谢 !!!!
根据您的代码,我会假设您尝试停止的服务器实例不是正在运行的实例。
相反,试试这个。
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秒钟并关闭它。
如果您想要停止在单独进程中运行的服务器,则需要查看使用套接字等内容来启用跨进程通信。
嗨疯了,你是什么意思的独立过程?单独的服务器类实例?我使用单例来确保我会得到相同的实例。谢谢.. – Willie 2013-04-23 03:01:20
如果你要用'start'作为命令行参数运行你的程序(按原样)。它会创建一个进程,在其中创建一个线程即服务器。此过程将只能创建服务器的单个实例。如果使用'start'作为命令行参数再次运行它,它将使用作为服务器的新线程创建一个新进程。这就是为什么你无法阻止它。每次运行该程序时,它都会创建一个单独的进程,该进程不知道您创建的所有其他进程/线程 – MadProgrammer 2013-04-23 03:04:55
感谢Mad,您的解释使场景变得更好,并且您有任何建议或想法可以阻止已启动的服务器通过命令?我想用java命令“java -cp JAR_FILES BOOTSTRAP_CLASS_NAME args”使用shell脚本,这里的参数将是[start,stop,status]。 – Willie 2013-04-23 03:22:17
我建议你用那样的脚本(当然,如果你的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
谢谢亚历克斯,请允许我以这种方式给你打电话..我完全理解我可以使用shell脚本,我之前使用过这种方式,但是简单地杀死这个进程并不是一个好方法来阻止服务器。所有的服务突然死亡可能会导致数据损坏或什么..“不是一个优雅的方式来停止服务器..” - 我看到这本书中的报价 :)但仍然谢谢你.. – Willie 2013-04-23 02:53:36
另一个更好也许,赶上杀死信号:http://stackoverflow.com/questions/2541597/how-to-gracefully-handle-the-sigkill-signal-in-java – 2013-04-23 03:15:03
谢谢亚历克斯..我还有很多要学习你们.. :) – Willie 2013-04-23 03:18:17
当你运行java第二次,它创建了一个全新的过程中,的。 stop()'调用没有以任何方式连接到第一个进程启动的s。 – Thomas 2013-04-23 02:36:44
为什么'tomcat'? – leonbloy 2013-04-23 02:36:52
你需要一个启动/停止脚本 – 2013-04-23 02:37:58