简体   繁体   中英

Java Thread not cleaning up

I'm currently attempting to write a Logger style thread. I'm not using the existing API because this is partially an exercise to improve my threading.

When the thread is interrupted, I need it to shutdown gracefully, flushing the last of it's queued messages and closing the file streams.

Currently, it shuts down but messages are often still in queue, and I'm concerned that the file streams aren't being closed gracefully.

This is my run()

while(!shutdown){
    writeMessages();
    try{
        Thread.sleep(5000);
    } 
    catch (InterruptedException e) {
    }
}try {
    writeMessages();
} catch (CustomException e1) {
    e1.printStackTrace();
}
try {
    logFile.close();
} catch (IOException e) {
    e.printStackTrace();
}
try {
    errFile.close();
} catch (IOException e) {
    e.printStackTrace();
}

Java has very neat way to shutdown threads. It's called interruption flag . When you want to interrupt thread you simply write following code:

thread.interrupt();
thread.join();

And in the Runnable of background thread you should check interruption flag and behave accordingly. If you want thread to survive until messages are left you can do it in a following manner (I assume you have some way of checking is there any messages left. In my case it's a BlockingQueue ):

Thread self = Thread.currentThread();
BlockingQueue<String> messages = ...;

while (!self.isInterrupted() || !messages.isEmpty()) {
  try {
    String message = messages.take();
    writeMessage(message);
  } catch (InterruptedException) {
    self.interrupt();
  }
}

One more thing. You should ensure that messages are not added to the queue after thread shutdown is requested or shutdown all threads generating messages before writing thread. This also could be done checking thread interruption flag (you need to know reference to a writer thread):

public void addMessage(String message) {
  if (thread.isInterrupted() || !thread.isAlive()) {
    throw new IllegalStateException();
  }
  messages.add(message);
}

Also I recommends you to see at java.util.concurrent package. It have a lot of useful tools for multithreaded applications.

使用finally块添加刷新指令。

所有其他评论都很好,我只想添加 - 确保在关闭它们之前在输出流上调用flush()。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM