我试图了解Java(和JVM)如何创建线程。

我在实践中阅读了Java Concurrency,我无法找到一个很好的解释,默认情况下,所有Java应用程序是单一还是multi-threaded。

一方面,来自开发人员的POV:我编写了一堆顺序代码而没有创建Thread实例或在任何地方实现Runnable。我需要同步吗?我应该制作double-sure我的课程是thread-safe吗?如果是这样,我应该停止使用具有可变字段的POJO吗?我读到JVM将为自己的业务创建多个线程。 JVM是否也在没有显式创建这些线程的情况下创建运行我的应用程序的线程?

另一方面:我编写了一堆代码,我在其中显式创建了Threads和Runnable实现。 JVM是否将其自己的线程分离到"help",我的multi-threaded代码运行得更快?

完全有可能我甚至没有以正确的方式考虑JVM的线程处理。但是,我是一名entry-level Java开发人员,我讨厌我发现这令人困惑。

分析解答

一般来说,除非您执行已知创建线程的操作,否则将不会创建与您编写的代码1交互的线程。创建Thread对象就是一个例子,但还有很多其他的。这是一个non-exhaustive list:

  • 使用使用线程的ExecutorExecutorService实现(大多数)。
  • 使用并发Stream方法,例如,通过使用parallelStream方法创建流。
  • 使用library方法在幕后创建线程。

因此,通常情况下,线程不会突然出现,而是由于您所做的事情。除了在您知道正在使用线程的地方之外,通常不需要担心cross-thread同步。因此,默认情况下,您的对象将不是线程安全的:但它们不应该是线程敌对的。线程充满敌意的对象是不能跨线程安全地使用同一类的不同对象的对象,例如,因为它们对共享静态状态进行不同步访问。

如果你知道你没有创建任何线程,你可以使用这样的thread-hostile对象,但这是一个不好的习惯。


1我正在对"interact with code you write"进行区分,因为典型的JVM将在幕后使用多个线程,即使你从不创建任何线程,也可以用于垃圾收集,调用终结器,监听JMX连接等内务处理任务。