我正在编写一个将启动多个线程的应用程序-每次执行的线程数量有所不同,但通常大于5个且小于100个-每个线程都会从Mongo数据库中重复读取。
public class MyThread implements Runnable {
private MyMongoClient myMongoClient = MyMongoClient.getInstance();
public MyThread() {
}
@Override
public void run() {
Document myDocument = myMongoClient.getDocumentById("id");
Document newDocument = new Document("id": "newId");
myMongoClient.writeDocument(newDocument);
}
}
我有一个现有的单例服务类来查询和更新Mongo,并且想要有关在线程中使用它的模式的任何建议吗?
public class MyMongoClient {
private static MyMongoClient INSTANCE = new MyMongoClient();
private myCollection;
private MyMongoClient() {
try (MongoClient mongoClient = new MongoClient(host)) {
MongoDatabase db = mongoClient.getDatabase("myDatabase");
myCollection = db.getCollection("myCollection");
}
}
public static MyMongoClient getInstance() {
return INSTANCE;
}
private Document getObjectById(String id) {
// Implementation
}
private write writeDocument(Document document) {
// Implementation
}
}
如图所示,每个线程将从现有条目中读取,但不会更新其中的任何条目,并将使用相同的服务写入新条目
每个线程应该使用相同的服务实例,还是应该重写服务,以便每个线程都有自己的实例?
答案 0 :(得分:1)
您将得到一个错误,因为您在该构造函数中关闭了MongoClient
。 MongoClient
有一个内置的连接池,因此没有必要创建多个连接池。仅创建一个并在线程之间共享。
答案 1 :(得分:-1)
您可以使用ThreadPoolExecutor
。它可以处理所有事情,您只需将任务提交到池中即可。
在我的示例中,keepAliveTime=10
秒,它的值取决于您的要求。
ExecutorService threadPoolExecutor = new ThreadPoolExecutor(
5,
100,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
);
请参阅Oracle Tutorial on the Executors框架。