我尝试使用Jetty和HttpServlet创建一个简单的API后端。我已经阅读here和here关于使用HttpServlet的线程安全的详细信息一般的共识似乎是这是在HttpServlerts中处理变量访问的正确方法:
public class MyServlet extends HttpServlet {
private static Object thisIsNotThreadsafe;
private Object thisIsAlsoNotThreadsafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadsafe;
thisIsNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
thisIsAlsoNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
thisIsThreadsafe = request.getParameter("foo"); // Good.
}
}
我要做的是创建一个新的MongoClient:
MongoClient mongoClient = new MongoClient("localhost", 27017);
我可以将其作为一个全局变量",但这不是线程安全的。每次调用doGet
或doPost
时,我都可以创建一个新实例。但MongoDB的Java驱动程序文档似乎也反对这一点:
具有内部连接池的MongoDB客户端。对于大多数应用程序,您应该为整个JVM安装一个MongoClient实例。
最好的方法是什么?
答案 0 :(得分:1)
如果MongoClient
实例是线程安全的并且可以由多个线程共享而不是并发瓶颈,那么您可以为共享MongoClient
实例实现Singleton包装器。
基于Mongo文档似乎在说什么,这将是最正确的"方法,特别是如果你有/可能有多个servlet类。
如果MongoClient
实例不是线程安全的,等等,那么您需要为MongoClient
实例实现某种(线程安全的)连接池。
如果您使用的是支持依赖注入(DI)的框架,那么还有其他解决方案可以避免显式单例和池的一些问题。