我們在服務器程序中經常用到日誌,日誌對於我們排查問題有很大的幫助。
下面是日誌服務的思路以及實現
思路:多個生產者單個消費者的設計方式,每個調用log的操作都相當於一個生產者,而後臺的日誌線程則相當於消費者。
public class LoggerService {
private final BlockingQueue<String> queue;
private final LoggerThread loggerThread;
private final PrintWriter writer;
private boolean isShutdown;
private int reservations;
public LoggerService(Writer writer) {
this.queue = new LinkedBlockingQueue<>();
this.loggerThread = new LoggerThread();
this.writer = new PrintWriter(writer);
}
public void start() {
loggerThread.start();
}
public void stop() {
synchronized (this) {
isShutdown = true;
}
loggerThread.interrupt();
}
public void log(String msg) throws InterruptedException {
synchronized (this) {
if (isShutdown) {
throw new IllegalStateException();
}
++reservations;
}
queue.put(msg);
}
private class LoggerThread extends Thread {
@Override
public void run() {
while (true) {
try {
synchronized (LoggerService.this) {
if (isShutdown && reservations == 0) {
break;
}
}
String msg = queue.take();
synchronized (LoggerService.this) {
--reservations;
}
writer.println(msg);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
writer.close();;
}
}
}
}
}