您的问题描述似乎符合生产者/消费者模式。
您有许多线程处理用户请求,这些请求将产生将信息写入数据库的请求。您将有一个(或多个)线程来处理这些请求并将数据写入数据库。
在 Java 中有很多方法可以实现这一点。你可以:
- 每次要将一条信息记录到数据库中时启动一个新线程
- 与有限数量的线程一起使用共享
ExecutorService
,这将被重用并避免多种开销
- 使用共享
BlockingQueue
,您将在其中放置来自您的 servlet 的日志请求,并take()
在一个循环中拥有一个(或多个)线程元素,并根据您采用的元素将数据写入数据库
在任何情况下,我都会将此逻辑封装在一个RequestLogger
类中,例如:
public class RequestLogger {
private final Thread thread;
private final BlockingQueue<LogRequest> logRequestQueue = new LinkedBlockingQueue<>();
public RequestLogger() {
this.thread = new Thread(new Runnable() {
@Override public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
final LogRequest req = logRequestQueue.take();
// ... log it to the database somehow ...
}
} catch (Exception e) { ... do something ... }
}
});
}
public void start() { thread.start(); }
public void stop() { thread.interrupt(); }
public void log(...) {
logRequestQueue.offer(new LogRequest(...));
}
}
你实例化这个类一次,调用.start()
,你就可以记录你想要的一切了。
如果您愿意(例如,因为您看到日志请求积累得太快),您可以更改while(...)
循环中的逻辑以一次接收更多请求(如果可用),并使您的代码发出一次写入数据库,或写入单个事务,或类似的东西。
这实际上取决于您的特定场景,但如果您遇到性能问题,那么瓶颈将是数据库。