Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java多线程环境中关闭线程_Java_Multithreading_Sockets - Fatal编程技术网

如何在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

因此,我的服务器应用程序造成了巨大的cpu使用率,平均约为95%。我认为原因是它不断产生新线程,但没有关闭它。当出现以下情况时,我应该如何关闭线程:刷新页面、注销、关闭浏览器

对于服务器部分,我的代码或多或少是这样的

ThreadedEchoServer.java

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小程序是否有这样的方法!