stopServer()
서버에서 Mac, Linux 및 UNIX 컴퓨터에서 완벽하게 작동하지만 Windows에서 닫으려고하면 최소 1 초가 소요됩니다. 각각은 ServerSocket
의 제한 시간으로 인해 소켓이 닫히도록합니다. Thread.join()
에 전화 할 때마다 한 번에 하나씩 반대로 Linux, Mac 등에서 모든 작업을 한꺼번에 닫을 수 있기를 바랍니다.스레드가 Windows에서 Thread.join()까지 중지되지 않음
서버 코드
public class FileServer {
private ArrayList<Thread> sockets = new ArrayList<>();
private ServerSocket fileServer;
public void startServer(int port, int maxThreads, int timeout) throws IOException {
fileServer = new ServerSocket();
fileServer.setPerformancePreferences(1, 0, 1);
fileServer.bind(new InetSocketAddress(port));
for (int threads = 0; threads < maxThreads; threads++) {
sockets.add(new Thread(new ServerInit(fileServer, timeout)));
System.out.println("Socket " + threads + " initialized...");
}
for (int socket = 0; socket < sockets.size(); socket++) {
(sockets.get(socket)).start();
System.out.println("Socket " + socket + " started!");
}
}
public void stopServer() {
if (fileServer.isBound()) {
for (int thread = 0; thread < sockets.size(); thread++) {
sockets.get(thread).interrupt();
}
for (int thread = 0; thread < sockets.size(); thread++) {
try {
if (sockets.get(thread).isAlive()) {
sockets.get(thread).join();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
class ServerInit implements Runnable {
private ServerSocket server;
private int timeout;
public ServerInit(ServerSocket server, int timeout) {
this.server = server;
this.timeout = timeout;
}
public void run() {
while (!Thread.interrupted()) {
try {
server.setSoTimeout(1000);
Socket client = server.accept();
client.setSoTimeout(timeout);
processRequest(receiveRequest(client), client);
client.close();
} catch (SocketTimeoutException ste) {
} catch (IOException io) {
io.printStackTrace();
}
}
System.out.println("Socket closed");
}
}
왜 그들이 while
루프를 종료하기 전에 그들과 합류하기 위해 저를 을 필요로하는 스레드가되어 있습니까? 테스트를 마쳤으며 모든 스레드가 시작되고 모든 스레드가 제대로 인터럽트되었는지 확인합니다.
또한 System.out.println()
을 while
루프에 넣으면 하나의 스레드 만 제대로 인쇄됩니다.
편집
나는 타임 아웃 시간 accept
기다려야한다는 것을 인식보다 훨씬 더 많은입니다. 즉, 1 초의 제한 시간입니다. 이 모든 작품 다른 플랫폼에서 완벽하게 작동합니다. 나는 모든 스레드를 중단하고 실제로 스레드가 멈추는 지 확인하기 위해 스레드에 합류합니다. 가장 큰 관심사는 이러한 스레드가 있어야 할 때 동시에 시간 초과되지 않는 이유입니다.
정확히 어떻게 상상하고 있습니까? 쓰레드가'accept'에 있고, 쓰레드가 중단됩니다. InterruptedException이 발생했다고 생각합니까? 규칙 상으로는 검사중인 모든 인터럽트 플래그가 지워집니다. –
Javadoc에는'ServerSocket.accept()'가 인터럽트 가능한 것이 없으므로 스레드는 모두 accept timeout을 기다리고 있습니다. 코드가 의도 한대로 작동합니다. 흥미로운 점은 일부 플랫폼에서는 더 빠르지 만 Windows에서 작동하는 방식에는 아무런 문제가 없다는 것입니다. 제목이 의미가 없습니다. – EJP
인터럽트 플래그를 검사하는 대신 스레드를 멈추기 위해'ServerInit' 클래스의 while 루프에서 휘발성 정적 변수 (세마포어)를 사용하지 않으시겠습니까? –