在Java线程中使用服务的最佳实践是什么?

时间:2019-01-05 01:39:27

标签: java mongodb-java java-threads

我正在编写一个将启动多个线程的应用程序-每次执行的线程数量有所不同,但通常大于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
    }    
}

如图所示,每个线程将从现有条目中读取,但不会更新其中的任何条目,并将使用相同的服务写入新条目

每个线程应该使用相同的服务实例,还是应该重写服务,以便每个线程都有自己的实例?

2 个答案:

答案 0 :(得分:1)

您将得到一个错误,因为您在该构造函数中关闭了MongoClientMongoClient有一个内置的连接池,因此没有必要创建多个连接池。仅创建一个并在线程之间共享。

答案 1 :(得分:-1)

您可以使用ThreadPoolExecutor。它可以处理所有事情,您只需将任务提交到池中即可。

在我的示例中,keepAliveTime=10秒,它的值取决于您的要求。

ExecutorService threadPoolExecutor = new ThreadPoolExecutor(
            5,
            100,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>()
    );

请参阅Oracle Tutorial on the Executors框架。