[心得] 從0開始 2.多執行緒
今天我們要來正式進入 multi-thread (多執行緒)的部分了
觀察之前的程式片段可以發現到有兩個 while 迴圈
一個負責建立連線, 另一個負責 echo
// 建立連線的迴圈
while (true) {
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
out.println("歡迎來到 telnet echo server!");
// 負責與使用者互動的迴圈
String input;
while ((input = in.readLine()) != null) {
if ("quit".equalsIgnoreCase(input)) {
out.println("Bye! 歡迎下次再來");
socket.close();
break;
}
out.println("Echo: " + input);
}
}
所以我們把負責與使用者互動的部分程式抽離出來
建立一個新的 Player class, 讓原本的 ChatServer 專心處理連線就好
// Player.class
// ✂--------------請沿虛線剪下--------------
package core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
// java 中程式要支援多執行緒需要實作 Runnable 介面
public class Player implements Runnable {
private Socket socket;
private BufferedReader in;
private PrintStream out;
// 建構子, 讓每個 Player 負責管理自己的 Socket 物件
public Player(Socket socket) throws IOException {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
}
// override Runnable.run() 在裡面實作我們需要的邏輯
// 其實就是之前第二個 while 迴圈的內容
@Override
public void run() {
write("歡迎來到 telnet echo server! (多執行續版本)");
try {
while (true) {
String input = read();
if ("quit".equalsIgnoreCase(input)) {
socket.close();
break;
}
write("Echo: " + input);
}
} catch (IOException ignored) {}
}
// 把之前的 in.readLine() 與 out.println() 包裝起來, 方便後續使用
public String read() throws IOException {
return in.readLine();
}
public void write(String message) {
out.println(message);
}
}
// ✂--------------請沿虛線剪下--------------
Player 實作完之後
原本的 ChatServer 的程式碼也變得比較乾淨了
// ChatServer.class
// ✂--------------請沿虛線剪下--------------
package service;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import core.Player;
public class ChatServer {
static final int PORT = 4000;
public static void main(String[] args) {
Socket socket;
try (ServerSocket server = new ServerSocket(PORT)) {
System.out.println("Server is listening port: " + PORT + " now");
while (true) {
socket = server.accept();
Player player = new Player(socket);
Thread thread = new Thread(player);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// ✂--------------請沿虛線剪下--------------
java 中只要新建一個 Thread 物件
並在建立時傳入剛才已經實作 Runnable 的 Player
接著再呼叫 thread.start(), Thread 就會去開一個新的執行緒去執行 player.run()
你現在可以嘗試多開幾個 client 試著連線到 localhost:4000
我們的 server 已經有能力同時服務許多使用者了
--
╔═◢ ◣═╦╦═════╦═════╗
║ ◤◤◤ ◥ ╠╣飛鳥ももこ╠═╗ ║
║ ▇ ▇ ║╚═════╝ ╚═╦═╣
║ ▌ ● ● ▌ ║╔══════╗╔═╩═╣
║◤ ◥ ︺█◤ ◥╠╣Momoko Asuka╠╝ ║
╚◣◢ ▄▂▄ ◣◢╩╩══════╩════╝
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 211.72.253.40 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/mud/M.1575524180.A.B87.html
※ 編輯: gasbomb (211.72.253.40 臺灣), 12/05/2019 13:56:30
→
12/06 16:08,
5年前
, 1F
12/06 16:08, 1F
→
12/06 16:09,
5年前
, 2F
12/06 16:09, 2F
→
12/06 16:09,
5年前
, 3F
12/06 16:09, 3F
mud 近期熱門文章
PTT遊戲區 即時熱門文章
-6
13
30
37
103
197