溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JAVA怎么實現自動關閉服務器

發布時間:2022-02-21 17:00:07 來源:億速云 閱讀:619 作者:iii 欄目:開發技術

今天小編給大家分享一下JAVA怎么實現自動關閉服務器的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

普通實現的服務器都無法關閉自身,只有依靠操作系統來強行終止服務程序。這種強行終止服務程序的方式盡管簡單方便,但會導致服務器中正在執行的任務突然中斷。如果服務器處理的任務非常重要,不允許被突然中斷,應該由服務器自身在恰當的時刻關閉自己

代碼如下:

  • EchoServer類

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客戶通信的ServerSocketserverSocket.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);//設定等待客戶連接的超時時間為60sserverSocket.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和SocketExceptionsocket=serverSocket.accept();//把等待客戶發送數據的超時時間設為60ssocket.setSoTimeout(60000);//可能會拋出RejectedExecutionExceptionexecutorService.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;}@Overridepublic 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();}}}}
  • AdminClient類(負責向EchoServer發送“shutdown”命令,關閉服務器)

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();}}}}
  • Client類(客戶,與服務器進行通訊)

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無法被加入線程池

  • EchoServer(只顯示連接了Client,未連接Client1)

  • Client

  • Client2(向服務器發送消息,收到null)

  • AdminClient(在Client沒有運行結束時,被阻塞)

當Client輸入“bye”結束運行后,AdminClient關閉服務器

  • Client類

  • EchoServer類

  • AdminClient類

以上就是“JAVA怎么實現自動關閉服務器”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女