在 java 个线程中使用服务的最佳做法是什么?

What is the best practise for using a service in 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);
    }
}

我有一个现有的单例服务 class 来查询和更新 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
    }    
}

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

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

您将收到错误消息,因为您在该构造函数中关闭了 MongoClientMongoClient 有一个内置的连接池,因此没有理由创建多个。只创建一个并在您的主题中分享它。

您可以使用 ThreadPoolExecutor。它处理一切,您只需将任务提交到池中。

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

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

参见 Oracle Tutorial on the Executors 框架。