我有以下代码,我希望能够使用多个线程来处理套接字,使用固定的线程池(例如Executors.newFixedThreadPool())
如何重构代码以利用线程池来处理传入连接?
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Thread {
public static final int PORT = 1025;
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
Socket s1 = serverSocket.accept();
ServerWorker m = new ServerWorker(s);
m.start();
ServerWorker n = new ServerWorker(s1);
n.sleep(2000);
n.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
工人阶级:
class ServerWorker extends Thread {
private Socket _socket;
public ServerWorker(Socket socket) {
this._socket = socket;
}
public void run() {
try {
saveFile(this._socket);
} catch (Exception e) {
}
// Thread should terminate when run returns.
}
private void saveFile(Socket socket) throws Exception {
/* do stuff */
}
}
答案 0 :(得分:1)
如果我正确理解你的问题,你基本上想要使用固定的线程池并行处理传入的连接,而不是在它们进入时任意产生线程。如果不是,我很抱歉错误地编辑了你的问题。
基本上,让您的ServerWorker实现Runnable(而不是扩展Thread,这是运行Runnable的特定方式)。你可以传递一个线程,但那只是......奇怪的。
然后,基本上,在你的接受循环中,你得到你的Socket,将它传递给新的ServerWorker可运行,然后将它提交给线程池。如果有容量,线程池将像以前一样执行它。如果没有,它将拒绝它。
我不清楚为什么你一次创造两个,所以更难具体说明你应该做什么。
答案 1 :(得分:1)
首先,您需要将ExecutorService
添加到Server
类,可能是作为成员。其次,您的ServerWorker
类需要实现Runnable
而不是扩展Thread
(无论如何,您应该习惯这样做)。第三,在Server
班级的主循环accept
连接中,为ServerWorker
创建一个新的submit
和ExecutorService
。
private final ExecutorService = Executors.newFixedThreadPool(4);
@SuppressWarnings({ "static-access", "resource" })
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
ServerWorker m = new ServerWorker(s);
executor.submit(m);
}
} catch (Exception e) {
e.printStackTrace();
}
}
完成后不要忘记关闭线程池。