[英]Java multi-threaded Server notify() IllegalMonitorStateException
[英]Making a basic Java file server multi-threaded
我有一台服務器向其客戶端發送文本文件的內容。
'server'包有一個' Main '(從cmd行args接收端口號並解析它),' Server '和' FileHandler '類,我想我已經在某種程度上得到它們(使用線程池)這樣服務器就能同時服務於兩個客戶端。
現在我正在嘗試構建一個CLI,其中包含啟動和停止服務器的選項。 我正在尋找實現2個線程,其中一個線程將監聽輸入,另一個線程將監聽'accept()'調用。
到目前為止,我嘗試創建一個新類' Commander.java '並在構造函數中接受一個AtomicBoolean ,然后將其存儲在對象中,以用作停止服務器線程的標志。
我希望正在收聽'accept()'調用的線程定期檢查是否已經停止了請求 - 我怎樣才能在我的'Commander'類中執行此操作?
包括一些代碼片段(也就是我到目前為止的嘗試),以便您更好地理解:
class Server implements Runnable
{
Socket sock;
ExecutorService executor;
private int port ;
public Server(int p) {
port = p ;
executor = Executors.newFixedThreadPool(2);
}
public void startServer() {
ServerSocket s = new ServerSocket(port);
...
while (true)
{
Socket temp = s.accept();
sock = temp;
executor.execute(new FileHandler(sock));
// serveFile(temp) ;
}
public void run() {
startServer();
}
}
public class Main {
public static void main(String[] args) {
while(true) {
System.out.println("Main menu:\n" +
" 1 - Start server\n"+
" 2 - Stop Server\n"+
" 0 - Exit");
int in = Integer.parseInt(scanner.nextLine());
switch(in) {
case 1:
// start server
System.out.println("Starting server...");
Thread th1 = new Thread(new Server(port));
th1.start();
System.out.println("Case continuity...");
// server.startServer() ;
break;
case 2:
// stop server
System.out.println("Server stopped.\n");
break;
case 0:
// exit
System.exit(0);
break;
}
}
}
}
class FileHandler implements Runnable {
Socket socket;
public FileHandler(Socket socket) {
this.socket = socket;
}
private void serveFile() {
...code for serving file...
}
public void run() {
serveFile();
}
}
public class Commander implements Runnable
{
private AtomicBoolean bool;
public Commander(AtomicBoolean bool) {
this.bool = new AtomicBoolean(bool);
}
public boolean value() {
return bool.get();
}
你的方法是錯的。 在accept()
上被阻塞的線程不應該做什么,而是在建立連接時等待並啟動新線程(或提交新任務)。
當您想要關閉服務器時,請在ServerSocket
上調用close()
(當然是從不同的線程)。 在accept()
上阻塞的線程將拋出SocketException
,然后您可以清理並退出。
基於@Kayaman 答案 :
A-在您的服務器類:
1-讓ServerSocket
成為類成員范圍:
ServerSocket s = new ServerSocket(port);
2-添加方法shutdown()
:
public void shutdown(){
try{
s.close();
}catch(Exception e){
e.printStacktrace();
}
}
3-添加try/catch
來處理套接字關閉(執行干凈關閉):
while (true)
{
try{
Socket temp = s.accept();
sock = temp;
executor.execute(new FileHandler(sock));
// serveFile(temp) ;
}catch(SocketException ex){
doAcleanShutdown();
}
}
B-在您的主要課程中:
1-讓Server
實例成為類成員范圍
Server myServer = new Server(port);
2-在交換機( case 1:
myServer
使用myServer
實例
case 1:
// start server
System.out.println("Starting server...");
Thread th1 = new Thread(myServer);
th1.start();
System.out.println("Case continuity...");
// server.startServer() ;
break;
3-停止服務器, case 2:
case 2:
// stop server
myServer.shutdown();
System.out.println("Server stopped.\n");
break;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.