【问题标题】:how to log my program every 10 seconds如何每 10 秒记录一次我的程序
【发布时间】:2026-02-11 08:05:01
【问题描述】:

您好,我有一个从服务器打印无限随机文本的程序 在一个while循环中并且不会停止 ,如何在文本文件中每 10 秒记录一次数据?

public class MyServer {
public static String str="";
private volatile boolean running=true;
public synchronized void  socketreceive(){
    try{
        ServerSocket ss=new ServerSocket(6666);
        Socket s=ss.accept();//establishes connection
        DataInputStream dis=new DataInputStream(s.getInputStream());
        str=(String)dis.readUTF();


       //this  continuously goes on  and I need to make a log from it
        System.out.println("message= "+str);


        ss.close();
    }catch(Exception e){}
}

public void receiver(){
 final Thread receive=new Thread(new Runnable() {
    @Override
    public void run() {
        while (running){
            socketreceive();
    }
    }

});

【问题讨论】:

  • 您需要启动一个线程,该线程将休眠 10 秒然后写入。如果你想更精确,你需要定义一个定时器,它会每 10 秒唤醒你的 writer 线程。
  • @Serge 我实际上需要所有输出的数据,我不明白睡眠是如何让我这样做的。
  • 那么,您手头有两个任务:保存转储之间的所有数据并每 10 秒转储一次,为下一部分清理内存。正确的?您需要添加一些同步以允许从读取器和写入器线程访问相同的内存区域。对于这个操作,最好有 2 个或更多内存区域,即让读取器填满一个内存区域,而写入器写入前一个区域,然后切换指针。

标签: java file logging timer


【解决方案1】:

对于这种情况,我有一个方便的计时器示例。唯一的缺点是它是一个“摆动”计时器,在你的情况下它可能是一个重量级的计时器。但是它有效。我添加了一些用于读写的骨架函数,可能会为您提供一些想法。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class TimedLogger {

    List<String>  strings;

    public mySocketReader() {
       ....
       String line = str=(String)dis.readUTF();
       storeLine(line);
       ..
     }

    synchronized void storeLine(String line) {
        strings.add(line);
    }
    synchronized void writeLines() {
       for(String s: strings)
           writeInFile(s);
       strings.clear();
    }

    Timer      timer = new Timer(10000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            writeLines();
        }
     });
}

因此,您的阅读器会将您的行保存在一个列表中,当有中断时,作者会将这些行写入文件中。由于函数是synchronized,它们不能同时执行,不能同时执行和同时修改列表。唯一的缺点是,在写入过程中,您不能在列表中添加任何新行。在写入完成之前,您无法有效地读取下一行。

您需要有 2 个(或更多列表)并使用同步函数来更改指向它们的指针。

【讨论】:

    【解决方案2】:

    您可以添加if-statement 来检查当前时间和上次记录时间之间的差异,如果其&gt;= 10 秒,则启动编写器线程。例如:

    public void run() {
            Date dt = new Date();
            DateFormat df = new SimpleDateFormat("ss");
            while (running){
                Date tmp = new Date();
                if (Integer.parseInt(df.format(tmp)) - Integer.parseInt(df.format(dt)) >= 10)
                    // start your writer thread
                    dt = tmp
                socketreceive();
        }
    

    【讨论】:

      【解决方案3】:

      这是一个如何实现可能的解决方案的示例,在此示例中,程序使用一个队列来存储来自多个套接字写入器的值。

      Queue<String> logValues = new LinkedList<>();
         public synchronized void log(String value) {
          logValues.add(value);
      }
      

      队列位于一个名为 BufferLogger 的类中,它实现了一个 Runnable 并等待 10 秒以获取队列的当前大小,具体取决于它继续使用从 0 迭代到队列大小并调用的 for 循环的大小队列中的 poll 方法,用于获取最新元素并将元素发送到日志文件,就像 FIFO 方法一样。

      @Override
      public void run() {
      
          int timeToSave = 10000; //10 seconds
          System.out.printf("Running Program Logger, log files every %d miliseconds. %s%n", timeToSave, new Date().toString());
      
          while (!Thread.currentThread().isInterrupted()) {
              try {
      
                  Thread.sleep(timeToSave);
                  this.writeToFile();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
      
      public void writeToFile() {
          Date date = new Date();
          File myLog = new File(String.format(filename));
          FileWriter myLogWritter = null;
          try {
              myLogWritter = new FileWriter(myLog, true);
      
              int queueSize = logValues.size();
              myLogWritter.write(String.format("Sending data to log!. Current Log Queue Size: %d.  Time:%s%n", queueSize, date.toString()));
              System.out.printf("Sending data to log!. Current Log Queue Size: %d.  Time:%s.  Filename:%s%n", queueSize, date.toString(), myLog.getName());
      
              for (int i = 0; i < queueSize; i++) {
                  myLogWritter.write(String.format("%s Logging Value: %s%n", date.toString(), logValues.poll()));
              }
      
          }
      

      我正在分享完整的代码以获取更多信息,希望这会有所帮助:

      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;
      import java.util.Date;
      import java.util.LinkedList;
      import java.util.Queue;
      import java.util.Random;
      
      
      public class ProgramLogger {
      
          static final int serverPort = 9999;
      
          public static void main(String args[]) {
              ServerSocket serverSocket = null;
              BufferLogger bufferLogger = new BufferLogger();
              new Thread(bufferLogger).start();
              Socket socket = null;
      
              try {
                  serverSocket = new ServerSocket(serverPort);
                  new ClientSender().start(); //client 1
                  new ClientSender().start(); //client 2
                  new ClientSender().start(); //client 3
                  new ClientSender().start(); //client 4
              } catch (IOException e) {
                  e.printStackTrace();
      
              }
              while (true) {
                  try {
                      socket = serverSocket.accept();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
      
                  new ServerReceptor(socket, bufferLogger).start();
              }
          }
      
      }
      
      
      class ClientSender extends Thread {
          Socket socket;
          PrintWriter out;
          String serverAddress="localhost";
          int serverPort=9999;
          Random randomValue = new Random();
      
          public void run() {
              try {
                  System.out.println("Sarting Client Sender on Thread " + Thread.currentThread().toString());
                  socket = new Socket(serverAddress, serverPort);
                  out = out == null ? new PrintWriter(socket.getOutputStream(), true) : out;
                  while (!Thread.currentThread().isInterrupted()) {
      
                      out.println(Thread.currentThread().toString() + " - " +  randomValue.nextInt(8000));
                      Thread.sleep(randomValue.nextInt(800));
      
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          }
      
      }
      
      class ServerReceptor extends Thread {
          protected Socket socket;
          private BufferLogger bufferLogger;
      
          public ServerReceptor(Socket clientSocket, BufferLogger bufferLogger) {
              this.socket = clientSocket;
              this.bufferLogger = bufferLogger;
          }
      
          public void run() {
              System.out.println("Sarting Server Receptor on Thread " + Thread.currentThread().toString());
              InputStream inputStream = null;
              BufferedReader bufferedReader = null;
              DataOutputStream dataOutputStream = null;
              try {
                  inputStream = socket.getInputStream();
                  bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
      
              } catch (IOException e) {
                  return;
              }
              String line;
              while (true) {
                  try {
                      line = bufferedReader.readLine();
                      if (line != null) {
                          bufferLogger.log(line);
                      }
      
                  } catch (IOException e) {
                      e.printStackTrace();
                      return;
                  }
              }
          }
      }
      
      class BufferLogger implements Runnable {
      
          Queue<String> logValues = new LinkedList<>();
          Date dateOfCreation = new Date();
          String filename = String.format("myapplog%d.log", dateOfCreation.getTime());
      
          public synchronized void log(String value) {
              logValues.add(value);
          }
      
          public void writeToFile() {
              Date date = new Date();
              File myLog = new File(String.format(filename));
              FileWriter myLogWritter = null;
              try {
                  myLogWritter = new FileWriter(myLog, true);
      
                  int queueSize = logValues.size();
                  myLogWritter.write(String.format("Sending data to log!. Current Log Queue Size: %d.  Time:%s%n", queueSize, date.toString()));
                  System.out.printf("Sending data to log!. Current Log Queue Size: %d.  Time:%s.  Filename:%s%n", queueSize, date.toString(), myLog.getName());
      
                  for (int i = 0; i < queueSize; i++) {
                      myLogWritter.write(String.format("%s Logging Value: %s%n", date.toString(), logValues.poll()));
                  }
      
              } catch (Exception ex) {
                  ex.printStackTrace();
              } finally {
                  try {
                      myLogWritter.close();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  }
      
              }
      
          }
      
          @Override
          public void run() {
      
              int timeToSave = 10000; //10 seconds
              System.out.printf("Running Program Logger, log files every %d miliseconds. %s%n", timeToSave, new Date().toString());
      
              while (!Thread.currentThread().isInterrupted()) {
                  try {
      
                      Thread.sleep(timeToSave);
                      this.writeToFile();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
      

      【讨论】: