文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么利用JAVA实现可以自行关闭服务器

2023-06-20 12:49

关注

这篇文章将为大家详细讲解有关怎么利用JAVA实现可以自行关闭服务器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

JAVA实现可以自行关闭的服务器

普通实现的服务器都无法关闭自身,只有依靠操作系统来强行终止服务程序。这种强行终止服务程序的方式尽管简单方便,但会导致服务器中正在执行的任务突然中断。如果服务器处理的任务非常重要,不允许被突然中断,应该由服务器自身在恰当的时刻关闭自己

代码如下:

package ShutdownServer;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.net.SocketTimeoutException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.RejectedExecutionException;import java.util.concurrent.TimeUnit;public class EchoServer {    private int port=8000;    private ServerSocket serverSocket;    private ExecutorService executorService; //线程池    private final int POOL_SIZE=4; //单个CPU时线程池中工作线程的数目    private int portForShutdown=8001; //用于监听关闭服务器命令的端口    private ServerSocket serverSocketShutdown;    private boolean isShutdown=false; //服务器是否已经关闭    private Thread shutdownThread=new Thread(){        //负责关闭服务器的线程        public void run(){            while(!isShutdown){                Socket socketForShutdown=null;                try{                    socketForShutdown=serverSocketShutdown.accept();                    BufferedReader br=new BufferedReader(                            new InputStreamReader(socketForShutdown.getInputStream())                    );                    String command=br.readLine();                    if (command.equals("shutdown")){                        long beginTime=System.currentTimeMillis();                        socketForShutdown.getOutputStream().write("服务器正在关闭\r\n".getBytes());                        isShutdown=true;                        //请求关闭线程池                        //线程池不再接收新的任务,但会继续执行完工作队列中现有的任务                        executorService.shutdown();                        //等待关闭线程池,每次等待的超时时间为30s                        //当使用awaitTermination时,主线程会处于一种等待的状态,等待线程池中所有的线程都运行完毕后才继续运行。                        //如果等待的时间超过指定的时间,但是线程池中的线程运行完毕,那么awaitTermination()返回true。执行分线程已结束                        //如果等待的时间超过指定的时间,但是线程池中的线程未运行完毕,那么awaitTermination()返回false。不执行分线程已结束                        //如果等待时间没有超过指定时间,等待!                        //可以用awaitTermination()方法来判断线程池中是否有继续运行的线程。                        while(!executorService.isTerminated())                            executorService.awaitTermination(30, TimeUnit.SECONDS);                            //关闭与EchoClient客户通信的ServerSocket                            serverSocket.close();                            long endTime=System.currentTimeMillis();                            socketForShutdown.getOutputStream().write(("服务器关闭,"+"关闭服务器用了"+(endTime-beginTime)+"ms\r\n").getBytes());                            socketForShutdown.close();                            serverSocketShutdown.close();                            System.out.println("服务器关闭");                    }                    else {                        socketForShutdown.getOutputStream().write("错误的命令\r\n".getBytes());                        socketForShutdown.close();                    }                } catch (Exception e) {                    e.printStackTrace();                }            }        }    };    public EchoServer() throws IOException {        serverSocket=new ServerSocket(port);        //设定等待客户连接的超时时间为60s        serverSocket.setSoTimeout(60000);        serverSocketShutdown=new ServerSocket(portForShutdown);        //创建线程池        executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);        shutdownThread.start();        System.out.println("服务器启动");    }    public void service(){        while(!isShutdown){            Socket socket=null;            try {                //可能会抛出SocketTimeoutException和SocketException                socket=serverSocket.accept();                //把等待客户发送数据的超时时间设为60s                socket.setSoTimeout(60000);                //可能会抛出RejectedExecutionException                executorService.execute(new Handler(socket));            }catch (SocketTimeoutException e){                //不必处理等待客户连接时出现的异常            }catch (RejectedExecutionException e) {                try {                    if (socket != null)                        socket.close();                } catch (IOException ex) {                    return;                }            }catch (SocketException e){                if (e.getMessage().indexOf("socket closed")!=-1)                    return;            }catch (IOException e){                e.printStackTrace();            }        }    }    public static void main(String[] args) throws IOException { //main方法抛出异常,异常直接交给虚拟机,虚拟机直接结束异常        new EchoServer().service();    }}//负责与单个客户通信的任务class Handler implements Runnable{    private Socket socket;    public Handler(Socket socket){        this.socket=socket;    }    private PrintWriter getWriter(Socket socket) throws IOException{        OutputStream socketOut=socket.getOutputStream();        return new PrintWriter(socketOut,true);    }    private BufferedReader getReader(Socket socket) throws IOException{        InputStream socketIn=socket.getInputStream();        return new BufferedReader(new InputStreamReader(socketIn));    }    public String echo(String msg){        return "echo: "+msg;    }    @Override    public void run() {        try{            System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort());            BufferedReader br=getReader(socket);            PrintWriter pw=getWriter(socket);            String msg=null;            //接收和发送数据,直到通信结束            while((msg=br.readLine())!=null){                System.out.println("from "+socket.getInetAddress()+":"+socket.getPort()+">"+msg);                pw.println(echo(msg));                if (msg.equals("bye"))                    break;            }        } catch (IOException e) {            e.printStackTrace();        }finally{            try{                if (socket!=null)                    socket.close();            }catch (IOException e){                e.printStackTrace();            }        }    }}
package ShutdownServer;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;public class AdminClient {    public static void main(String[] args){        Socket socket=null;        try{            socket=new Socket("localhost",8001);            //发送关闭命令            OutputStream socketOut=socket.getOutputStream();            //Scanner scanner=new Scanner(System.in);            //String order=scanner.next();            socketOut.write("shutdown\r\n".getBytes());            //接收服务器反馈            BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));            String msg=null;            while ((msg=br.readLine())!=null){                System.out.println(msg);            }        } catch (Exception e) {            e.printStackTrace();        }finally {            try{                if (socket!=null)                    socket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}
package ShutdownServer;import java.io.*;import java.net.Socket;public class Client {    private String host="localhost";    private int port=8000;    private Socket socket;    public Client() throws IOException {        socket=new Socket(host,port);    }    private PrintWriter getWriter(Socket socket) throws IOException{        OutputStream socketOut=socket.getOutputStream();        return new PrintWriter(socketOut,true);    }    private BufferedReader getReader(Socket socket) throws IOException{        InputStream socketIn=socket.getInputStream();        return new BufferedReader(new InputStreamReader(socketIn));    }    public void talk() throws IOException{        try{            BufferedReader br=getReader(socket);            PrintWriter pw=getWriter(socket);            BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));            String msg=null;            while((msg=localReader.readLine()) != null){                pw.println(msg);                System.out.println(br.readLine());                if (msg.equals("bye")){                    break;                }            }        }catch (IOException e){            e.printStackTrace();        }        finally {            try{                socket.close();            }catch (IOException e){                e.printStackTrace();            }        }    }    public static void main(String args[]) throws IOException {        new Client().talk();    }}

shutdownThread线程负责关闭服务器,它一直监听8001端口,如果接收到了AdminClient发送的“shutdown”命令,就把isShutdown设置为true。

在关闭服务器时,我们使用了最常用的方法,先调用线程池的shutdown()方法,接着调用线程池的awaitTermination()方法。

executorService.shutdown();                        //等待关闭线程池,每次等待的超时时间为30s                        //当使用awaitTermination时,主线程会处于一种等待的状态,等待线程池中所有的线程都运行完毕后才继续运行。                        //如果等待的时间超过指定的时间,但是线程池中的线程运行完毕,那么awaitTermination()返回true。执行分线程已结束                        //如果等待的时间超过指定的时间,但是线程池中的线程未运行完毕,那么awaitTermination()返回false。不执行分线程已结束                        //如果等待时间没有超过指定时间,等待!                        //可以用awaitTermination()方法来判断线程池中是否有继续运行的线程。                        while(!executorService.isTerminated())                            executorService.awaitTermination(30, TimeUnit.SECONDS);

在线程池执行了shutdown()方法后,线程池不会在接收新的任务,同时该线程因为调用awaitTermination()方法而发生阻塞,直到线程池中所有线程的任务执行完毕,该线程才会继续向下

运行结果

先运行EchoServer,Client,AdminClient后,再开启一客户程序Client1,显示Client1无法被加入线程池

怎么利用JAVA实现可以自行关闭服务器

怎么利用JAVA实现可以自行关闭服务器

怎么利用JAVA实现可以自行关闭服务器

怎么利用JAVA实现可以自行关闭服务器

当Client输入“bye”结束运行后,AdminClient关闭服务器

怎么利用JAVA实现可以自行关闭服务器

怎么利用JAVA实现可以自行关闭服务器

怎么利用JAVA实现可以自行关闭服务器

关于“怎么利用JAVA实现可以自行关闭服务器”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯