如何在java多线程环境中关闭线程
因此,我的服务器应用程序造成了巨大的cpu使用率,平均约为95%。我认为原因是它不断产生新线程,但没有关闭它。当出现以下情况时,我应该如何关闭线程:刷新页面、注销、关闭浏览器 对于服务器部分,我的代码或多或少是这样的 ThreadedEchoServer.java如何在java多线程环境中关闭线程,java,multithreading,sockets,Java,Multithreading,Sockets,因此,我的服务器应用程序造成了巨大的cpu使用率,平均约为95%。我认为原因是它不断产生新线程,但没有关闭它。当出现以下情况时,我应该如何关闭线程:刷新页面、注销、关闭浏览器 对于服务器部分,我的代码或多或少是这样的 ThreadedEchoServer.java public class ThreadedEchoServer { // using port 2000 static final int PORT = 2000; public static void ma
public class ThreadedEchoServer {
// using port 2000
static final int PORT = 2000;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new EchoThread(socket).start();
}
}
}
EchoThread.java
/*
Class for java server to accept incoming stream
and create a new thread to save log file data in server
*/
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
/*Create a File*/
int i = 1;
try {
File directory = new File("F:/temp/tmplog/" + getDate());
if(!directory.exists()) {
directory.mkdir();
}
String fileName = "F:/temp/tmplog/" + getDate() + "/" + getDateTime() + ".txt";
File file = new File(fileName);
//Double Make Sure it create the file
while(file.exists()) {
file = new File(fileName + "." + i);
i++;
}
FileOutputStream fis = new FileOutputStream(file, true);
PrintStream out = new PrintStream(fis);
System.setOut(out);
while (true) {
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
fis.close();
}
}
} catch (IOException ignored) {
}
}
此服务器应用程序基本上将为每个线程/客户端打开一个新的日志文件并写入日志文件。我想问题是我使用后没有关闭线程。这就是为什么它一直在产生新的线程。。有什么帮助吗?如果我明白你在找什么,你可以用超时来处理这种情况。 当超时过期时,您只需终止线程 回声线
/*
Class for java server to accept incoming stream
and create a new thread to save log file data in server
*/
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
this.socket.setSoTimeout(10000); //Sets timeout to 10 seconds
}
public void run() {
/*Create a File*/
int i = 1;
try {
File directory = new File("F:/temp/tmplog/" + getDate());
if(!directory.exists()) {
directory.mkdir();
}
String fileName = "F:/temp/tmplog/" + getDate() + "/" + getDateTime() + ".txt";
File file = new File(fileName);
//Double Make Sure it create the file
while(file.exists()) {
file = new File(fileName + "." + i);
i++;
}
FileOutputStream fis = new FileOutputStream(file, true);
PrintStream out = new PrintStream(fis);
System.setOut(out);
while (true) {
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
fis.close();
}
}
} catch (IOException ignored) {
} catch (SocketException e) { //Exception thrown by timeout
socket.close(); //We close the socket
this.stop(); //We stop the thread
}
}
如果我明白你在找什么,你可以用一个超时来处理这种情况。 当超时过期时,您只需终止线程 回声线
/*
Class for java server to accept incoming stream
and create a new thread to save log file data in server
*/
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
this.socket.setSoTimeout(10000); //Sets timeout to 10 seconds
}
public void run() {
/*Create a File*/
int i = 1;
try {
File directory = new File("F:/temp/tmplog/" + getDate());
if(!directory.exists()) {
directory.mkdir();
}
String fileName = "F:/temp/tmplog/" + getDate() + "/" + getDateTime() + ".txt";
File file = new File(fileName);
//Double Make Sure it create the file
while(file.exists()) {
file = new File(fileName + "." + i);
i++;
}
FileOutputStream fis = new FileOutputStream(file, true);
PrintStream out = new PrintStream(fis);
System.setOut(out);
while (true) {
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
fis.close();
}
}
} catch (IOException ignored) {
} catch (SocketException e) { //Exception thrown by timeout
socket.close(); //We close the socket
this.stop(); //We stop the thread
}
}
您能否放置一个
println
以查看它是否离开此循环:while(file.exists())…
?另一个在run
方法的末尾,查看线程是否退出?当然-调试EchoThread并找出客户端关闭连接时发生的情况。“catch(IOException)”是否发生?如果是,你在那里做什么?是否应该有一个返回以便finally可以执行,关闭套接字并退出线程?@MartinJames我不确定的部分是线程是否会在((line=br.readLine())!=null){}时退出,因为它会一直等待新的流。我想知道如果用户刷新页面或关闭浏览器会发生什么?它会自动退出循环吗,或者我如何确保它退出循环。我不知道。如果浏览器关闭连接,我希望readLine()包装的recv()或其他内容返回0。我认为readLine()应该抛出一些东西吗?你能放一个println
看看它是否离开这个循环:while(file.exists())…
?另一个在run
方法的末尾,查看线程是否退出?当然-调试EchoThread并找出客户端关闭连接时发生的情况。“catch(IOException)”是否发生?如果是,你在那里做什么?是否应该有一个返回以便finally可以执行,关闭套接字并退出线程?@MartinJames我不确定的部分是线程是否会在((line=br.readLine())!=null){}时退出,因为它会一直等待新的流。我想知道如果用户刷新页面或关闭浏览器会发生什么?它会自动退出循环吗,或者我如何确保它退出循环。我不知道。如果浏览器关闭连接,我希望readLine()包装的recv()或其他内容返回0。我认为readLine()应该抛出一些东西?在您的解决方案中,它会起作用,但是如果用户只是打开页面,一个小时后,或者两个小时后,他们突然想要发送一些东西,这意味着不会写入日志,因为线程已经关闭。有没有办法防止这种情况发生?将超时更改为一小时或更长时间。如果可能的话,最好的解决方案是,检测用户是否离开小程序,例如注销、刷新或转到其他页面,并仅在该事件期间关闭线程。有什么例子吗?谢谢,您应该寻找onClose()
方法或类似的方法,但我不知道Java小程序是否有这样的方法!对于您的解决方案,它会起作用,但是如果用户只是打开页面,一个小时后,或者两个小时后,他们突然想要发送一些东西,这意味着不会写入日志,因为线程已经关闭。有没有办法防止这种情况发生?将超时更改为一小时或更长时间。如果可能的话,最好的解决方案是,检测用户是否离开小程序,例如注销、刷新或转到其他页面,并仅在该事件期间关闭线程。有什么例子吗?谢谢,您应该寻找onClose()
方法或类似的方法,但我不知道Java小程序是否有这样的方法!