2012-04-30 2 views
1

Итак, мое приложение-сервер вызывает огромное использование процессора около 95%. Я думаю, что причина в том, что он не создает новую нить, но не закрывает ее. как я предполагаю закрыть поток, когда это произойдет: обновить страницу, выйти из системы, закрыть браузер.Как закрыть поток в многопоточной среде java

Мой код более или менее подобен этому для части сервера.

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) { 
     } 
    } 

Этот сервер приложений поясню откроет новый и писать в лог-файл для каждого потока/клиента. Я думаю, проблема в том, что я не закрываю поток после использования. вот почему он просто продолжает размножать новую тему .. Любая помощь?

+0

Вы можете поместить 'println', чтобы увидеть, если он выходит из этого цикла:' в то время как (File.Exists()) ... '? И еще один из них в конце метода «run», чтобы посмотреть, завершаются ли потоки? – Tudor

+0

Уверен - отлаживаем EchoThread и узнаем, что происходит, когда клиент закрывает свое соединение. Выходит ли «catch (исключение IOException)»? Если да, что вы там делаете? Должно ли быть возвращение, чтобы окончательно выполнить, закройте сокет и выйдите из потока? –

+0

@MartinJames часть, которую я не уверен, будет ли поток завершаться while ((line = br.readLine())! = Null) {}, так как он будет продолжать ждать нового потока. Мне было интересно, что произойдет, если пользователь обновит страницу или закроет браузер? будет ли он автоматически выйти из этого цикла или как я могу убедиться, что он вышел из цикла. – Harts

ответ

1

Если я понял, что вы ищете, вы можете просто использовать таймаут, чтобы справиться с этой ситуацией. Когда истечет время ожидания, вы просто прекратите поток.

EchoThread

/* 
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 
     } 
    } 
+0

с вашим решением, это сработает, но что произойдет, если пользователь просто поместит страницу, а через час или через два часа они вдруг захотят что-то отправить, это значит, что не будет записи журнала, поскольку нить уже закрыта. есть ли вообще предотвратить это? кроме изменения тайм-аута на час или больше. Лучшее решение, даже если это возможно, - обнаружить, удалился ли пользователь от апплета, например, выйти из системы, обновить или перейти на другую страницу и закрыть поток только во время этого события. любой пример? Спасибо – Harts

+0

Вы должны искать метод 'onClose()' или что-то вроде этого, но я не знаю, есть ли у Java-апплетов такой метод! – StepTNT

Смежные вопросы