但在计算机数据处理的情况下,当我们听到工作线程同时执行时,我们会自动地假设它们实际上执行了它们被编程为并行执行的任务。只有在我们深入研究了这样一个系统之后,我们才意识到,只有当线程分别由不同的 CPU 执行时,这样的并行处理才是可能的。否则,它们的时间共享相同的处理能力,我们认为它们在同一时间工作只是因为它们使用的时间间隔非常短——只是我们在日常生活中使用的时间单位的一小部分。当线程共享同一资源时,在计算机科学中,我们说它们同时执行。
关键区别在于,可以作为 VM 传递的捆绑包包括整个操作系统(部署了应用程序)。因此,运行两个虚拟机的物理服务器很可能运行两个不同的操作系统。相比之下,运行三个容器化应用程序的物理服务器(或 VM)只有一个运行的操作系统,两个容器共享(只读)操作系统内核,每个容器都有自己的访问(装载)来写入它们不共享的资源。例如,这意味着启动时间要短得多,因为启动容器不需要我们启动操作系统(如 VM)。
我们无法对`calculator.jar`进行模块化,因为它依赖于另一个非模块化代码`jackson-databind`,我们无法对`jackson-databind`进行模块化,因为它不是由我们维护的。这意味着我们无法实现应用程序的 100%模块化。在本配方的开头,我们向您介绍了未命名的模块。我们在类路径中的所有非模块代码都分组在未命名的模块中,这意味着所有与 jackson 相关的代码仍然可以保留在未命名的模块中,我们可以尝试模块化`calculator.jar`。但是我们不能这样做,因为`calculator.jar`不能声明对`jackson-databind-2.8.4.jar`的依赖关系(因为它是一个未命名的模块,命名的模块不能声明对未命名模块的依赖关系)。
我们无法对`calculator.jar`进行模块化,因为它依赖于另一个非模块化代码`jackson-databind`,我们无法对`jackson-databind`进行模块化,因为它不是由我们维护的。这意味着我们无法实现应用程序的 100%模块化。在本配方的开头,我们向您介绍了未命名的模块。我们在类路径中的所有非模块代码都分组在未命名的模块中,这意味着所有与 jackson 相关的代码仍然可以保留在未命名的模块中,我们可以尝试模块化`calculator.jar`。但是我们不能这样做,因为`calculator.jar`不能声明对`jackson-databind-2.8.4.jar`的依赖关系(因为它是一个未命名的模块,命名的模块不能声明对未命名模块的依赖关系)。
解决这个问题的一种方法是将与 jackson 相关的代码作为自动模块。我们可以通过移动与 jackson 相关的JAR来实现这一点: