使用共享对象实例化多个 Runnable 的含义?

Implications of instantiating multiple Runnable with shared objects?

我有一个旨在多线程的程序。我有一个 ProcessRunnable class 来处理需要大量 IO 的数据。 ProcessRunnable classes 都是 运行 在单独的线程中,但使用客户端/实用程序的共享实例实例化 类.

示例:

Client client = new Client();
Util util = new Util();

List<Runnable> runnables = new ArrayList<>();

for (int i; i < THREAD_COUNT; i++) {
    runnables.add(ProcessRunnable
                       .builder()
                       .client(client)
                       .util(util)
                       .build());
}

runnables.forEach(runnable -> new Thread(runnable).start());

我很好奇在 运行nables 中重用相同的 classes 实例是否会阻塞行为并导致我的程序变成单线程?

这里:

runnable -> new Thread(runnable).start()

真正使您的代码成为多线程的关键点是调用线程对象的 start() 方法。如果您只是调用线程 class 的 运行 方法,那么您实际上最终会由 "enclosing" 线程完成所有工作。

最后,请注意直接使用 "bare" 线程并不理想。了解它是可以的,但是 Java 提供了重要的抽象,例如 ExecutorService ,出于各种原因应该改用它。

避免原始线程的主要原因:您必须手动控制所有细微的细节。应该使用多少个线程?池化和共享线程怎么样(创建线程会带来很多开销,因此在现实世界中,您会避免为单个任务创建线程然后将其丢弃,就像您的代码那样)。除此之外:通常您想要解决业务问题。您想要使用多个线程来防止出现瓶颈情况。示例:您想通过网络并行发出多个请求以获取和处理数据。那么你真的只关心最终结果,而不关心低级线程的微妙之处!然后你可以使用 Future 或 CompleteableFuture 对象。

只需使用搜索引擎并研究这些术语,您就会发现很多 material。