提交 2a0aec4f 编写于 作者: W wizardforcel

2021-06-27 22:42:46

上级 57f5159a
......@@ -662,9 +662,9 @@ public class ThreadIntermingling {
在前面的示例中,由于我们提交了`Runnable`对象,而不是`Callable`对象,所以`Future`没有返回值。在这种情况下,不使用传递给`Future`的值。通常是`null`,但这并不是什么可依赖的。
最后也是最重要的一件事,许多开发人员都错过了,即使是我,在多年没有使用代码编写多线程 JavaAPI 之后,就是关闭了`ExecutorService`。创建了`ExecutorService`,它有`Thread`个元素。当所有非守护进程线程停止时,JVM 将停止。”直到胖女人唱歌,一切才结束。”
最后也是最重要的一件事,许多开发人员都错过了,即使是我,在多年没有使用代码编写多线程 JavaAPI 之后,就是关闭了`ExecutorService`。创建了`ExecutorService`,它有`Thread`个元素。当所有非守护线程停止时,JVM 将停止。”直到胖女人唱歌,一切才结束。”
如果线程在启动前被设置为守护进程(调用`setDaemon(true)`),那么它就是守护进程线程。一个自动成为启动它的守护进程线程的线程也是守护进程线程。当所有其他线程都完成并且 JVM 想要完成时,守护进程线程被 JVM 停止。JVM 本身执行的一些线程是守护进程线程,但是在应用中创建守护进程线程可能没有实际用途。
如果线程在启动前被设置为守护进程(调用`setDaemon(true)`),那么它就是守护线程。一个自动成为启动它的守护线程的线程也是守护线程。当所有其他线程都完成并且 JVM 想要完成时,守护线程被 JVM 停止。JVM 本身执行的一些线程是守护线程,但是在应用中创建守护线程可能没有实际用途。
不关闭服务只会阻止 JVM 停止。在`main`方法完成后,代码将挂起。为了告诉`ExecutorService`不需要它拥有的线程,我们必须`shutdown`服务。呼叫只会启动关机并立即返回。在这种情况下,我们不想等待。无论如何,JVM 都会这样做。如果我们需要等待,我们将不得不调用`awaitTermination`
......
......@@ -8,7 +8,7 @@
* 集合实用程序
* 数组实用程序
* 对象实用程序
* `java.time`
* `java.time`
# 列表、集合和映射接口
......@@ -597,7 +597,7 @@ ApacheCommons 项目中的`org.apache.commons.collections4.CollectionUtils`类
* 转换集合的方法
* 从集合中选择并过滤集合的方法
* 生成两个集合的并集、交集或差集的方法
* 方法创建不可变的空集合
* 创建不可变的空集合的方法
* 检查集合大小和空性的方法
* 反转数组的方法
......@@ -861,7 +861,7 @@ for(String e: list){
`ObjectUtils`课的所有方法可分为七组:
* 对象克隆方法
* 支持比较两个对象的方法
* 比较两个对象的方法
* 比较两个对象是否相等的`notEqual()`方法,其中一个或两个对象可以是`null`
* 几个`identityToString()`方法生成所提供对象的`String`表示,就像由`toString()`生成一样,这是`Object`基类的默认方法,并且可选地将其附加到另一个对象
......@@ -1217,8 +1217,8 @@ System.out.println(duration.getNano()); //prints: 0
5. 接口`java.util.Collection`的实现允许什么?选择所有适用的选项:
1. 将另一个集合的元素添加到集合中
2. 从集合中删除作为另一个集合的元素的对象
3. 只修改属于另一个集合的集合元素
2. 从集合中删除另一个集合的元素
3. 只修改属于另一个集合的元素
4. 从集合中删除不属于其他集合的对象
6. 选择`List`接口方法的所有正确语句:
......
......@@ -47,7 +47,7 @@ JCL 是实现该语言的包的集合。更简单地说,它是 JDK 中包含
* `System`类:提供对重要系统操作和标准输入输出的访问(在本书的每个代码示例中,我们都使用了`System.out`对象)
* `Runtime`类:提供对执行环境的访问
* `Thread``Runnable`接口:创建 Java 线程的基础
* `Iterable`接口:迭代语句使用
* `Iterable`接口:迭代语句使用
* `Math`类:提供基本数值运算的方法
* `Throwable`类:所有异常的基类
* `Error`类:一个异常类,它的所有子类都用来传递应用不应该捕捉到的系统错误
......@@ -168,8 +168,8 @@ JavaFX 基于**层叠样式表**(**CSS**),将平滑动画、Web 视图、
1. 右键单击要测试的类名
2. 选择“转到”
3. 选择测试
4. 单击创建新测试
3. 选择“测试”
4. 单击“创建新测试”
5. 单击要测试的类的方法的复选框
6. 使用`@Test`注释为生成的测试方法编写代码
......@@ -403,7 +403,7 @@ Apache Commons 项目包括以下三个部分:
要想得到一个在这个包或它的一个子包中不存在的集合类型或集合实用程序,必须很困难。以下只是包含的功能和实用程序的高级列表:
* `Bag`每个对象有多个副本的集合接口
* `Bag`集合接口,具有每个对象的多个副本
* 实现`Bag`接口的十几个类;例如,下面是如何使用`HashBag`类:
```java
......@@ -504,7 +504,7 @@ System.out.println(decodedStr); //prints: Hello, World!
# 测验
1. 什么是 Java 类库?选择所有适用的选项:
1. 编译类的集合
1. 编译后的类的集合
2. Java 安装附带的包
3. Maven 自动添加到类路径的`.jar`文件
4. 任何用 Java 编写的库
......
......@@ -6,12 +6,12 @@
* 线程与进程
* 用户线程与守护进程
* 扩展类线程
* 实现接口`Runnable`
* 扩展线程类
* 实现`Runnable`接口
* 扩展线程与实现`Runnable`
* 使用线程池
* 从线程获取结果
* 并行与并处理
* 并行与并处理
* 同一资源的并发修改
# 线程与进程
......@@ -29,9 +29,9 @@ Java 有两个执行单元:进程和线程。一个**进程**通常代表整
在计算机科学中,术语**守护进程**有更普通的用法,用于*作为后台进程运行,而不是由交互用户直接控制*的计算机程序。这就是为什么 Java 中有以下两种类型的线程:
* 用户线程(默认),由应用启动(主线程就是这样一个例子)
* 后台工作以支持用户线程活动的守护线程
* 在后台工作来支持用户线程活动的守护线程
这就是为什么所有守护进程线程在最后一个用户线程退出之后立即退出,或者在未处理的异常之后被 JVM 终止。
这就是为什么所有守护线程在最后一个用户线程退出之后立即退出,或者在未处理的异常之后被 JVM 终止。
# 扩展`Thread`类
......@@ -72,7 +72,7 @@ private static void pauseOneSecond(){
}
```
我们现在可以使用`MyThread`类来运行两个线程—一个用户线程和一个守护进程线程:
我们现在可以使用`MyThread`类来运行两个线程—一个用户线程和一个守护线程:
```java
public static void main(String... args) {
......@@ -94,7 +94,7 @@ public static void main(String... args) {
![](img/eed5c70b-11cd-45ca-aa9a-b0dfadc190c6.png)
前面的屏幕截图显示,只要最后一个用户线程(本例中的主线程)退出,守护进程线程就会自动退出。
前面的屏幕截图显示,只要最后一个用户线程(本例中的主线程)退出,守护线程就会自动退出。
# 实现`Runnable`接口
......@@ -146,7 +146,7 @@ public static void main(String... args) {
![](img/8558468b-719b-4a94-8dd9-d88c70d0ab75.png)
守护进程线程(名为`Two`的线程)在最后一个用户线程存在后退出,它与`MyThread`类的情况完全相同。
守护线程(名为`Two`的线程)在最后一个用户线程存在后退出,它与`MyThread`类的情况完全相同。
# 扩展线程与实现`Runnable`
......@@ -234,7 +234,7 @@ class MyRunnable implements Runnable {
2. 确保池不接受更多线程
3. 等待一段固定的时间,让所有线程完成它们所做的事情
4. 停止(中断)未完成任务的线程
5. 出口
5. 退出
以下代码执行前面列表中描述的所有操作:
......@@ -523,7 +523,7 @@ class MyCallable implements Callable {
如您所见,有许多方法可以从线程中获得结果。选择的方法取决于应用的特定需要。
# 并行与并处理
# 并行与并处理
当我们听到工作线程同时执行时,我们会自动地假设它们实际上做了编程所要并行执行的事情。只有在我们深入研究了这样一个系统之后,我们才意识到,只有当线程分别由不同的 CPU 执行时,这种并行处理才是可能的。否则,它们的时间共享相同的处理能力。我们认为他们在同一时间工作,只是因为他们使用的时间间隔非常短,只是我们在日常生活中使用的时间单位的一小部分。当线程共享同一个资源时,在计算机科学中,我们说它们同时进行。
......@@ -831,15 +831,15 @@ System.out.println("\n" + list); //prints: [One, Two, Three, Three]
2. 选择所有正确的语句:
1. 守护进程是一个用户线程
2. 守护进程线程在第一个用户线程完成后退出
3. 守护进程线程在最后一个用户线程完成后退出
2. 守护线程在第一个用户线程完成后退出
3. 守护线程在最后一个用户线程完成后退出
4. 主线程是一个用户线程
3. 选择所有正确的语句:
1. 所有线程都有`java.lang.Thread`作为基类
2. 所有螺纹延伸`java.lang.Thread`
2. 所有线程扩展`java.lang.Thread`
3. 所有线程实现`java.lang.Thread`
4. 守护进程线程不扩展`java.lang.Thread`
4. 守护线程不扩展`java.lang.Thread`
4. 选择所有正确的语句:
1. 任何类都可以实现`Runnable`接口
......@@ -866,9 +866,9 @@ System.out.println("\n" + list); //prints: [One, Two, Three, Three]
4. `Future`对象表示线程
8. 选择所有正确的语句:
1.处理可以并行进行
1.处理可以并行进行
2. 只有在计算机上有几个 CPU 或内核的情况下,才能进行并行处理
3. 并行处理是并处理
3. 并行处理是并处理
4. 没有多个 CPU,就不可能进行并发处理
9. 选择所有正确的语句:
......
......@@ -8,7 +8,7 @@ JVM 只是根据编码逻辑执行指令的执行器。它还发现并将应用
本章将讨论以下主题:
* Java 应用执行
* Java 应用执行
* Java 进程
* JVM 结构
* 垃圾收集
......@@ -303,9 +303,9 @@ JVM 通常被称为 **JVM 实例**。这是因为每次执行一个`java`命令
有两个子系统运行所有 JVM 内部进程:
* **类加载器**:读取`.class`文件,用类相关数据填充 JVM 内存中的方法区:
* 静态
* 静态字段
* 方法字节码
* 描述类的元数据
* 描述类的元数据
* **执行引擎**:使用以下方式执行字节码:
* 对象实例化的堆区域
* Java 和本机方法栈,用于跟踪调用的方法
......@@ -429,7 +429,7 @@ JVM 架构可以描述为有两个子系统:**类加载器**和**执行引擎*
如果其中任何一个是用户线程(默认值),那么 JVM 实例即使在主线程退出之后也会继续运行。只有在所有用户线程完成之后,JVM 实例才会停止。主线程可以请求子用户线程完成。但在退出之前,JVM 将继续运行。这意味着应用仍然在运行。
但是,如果所有子线程都是守护进程线程,或者没有子线程在运行,那么只要主应用线程退出,JVM 实例就会停止运行。
但是,如果所有子线程都是守护线程,或者没有子线程在运行,那么只要主应用线程退出,JVM 实例就会停止运行。
应用在异常情况下如何退出取决于代码设计。在讨论异常处理的最佳实践时,我们在第 4 章、“处理”中对此进行了讨论。如果线程捕获了`main(String[])``try-catch`块或类似高级方法中的所有异常,那么由应用(以及编写代码的程序员)决定如何最好地继续—尝试更改输入数据并重复生成异常的代码块,记录错误并继续,或者退出。
......
......@@ -320,7 +320,7 @@ public static void main(String[] args) throws IOException,
}
```
虽然这是一个守护进程,但我们将它作为普通线程而不是守护进程线程启动。当一个线程被设置为守护进程线程时,它不会使 JVM 保持活动状态。当所有其他非守护进程线程停止时,JVM 将退出,守护进程线程将停止。在我们的例子中,我们执行的守护进程线程是保持代码运行的唯一线程。在启动之后,主线程就没有什么事情可做了,但是 JVM 应该保持活动状态,直到运算符发出 Unix`kill`命令或在命令行上按`Ctrl + C`将其杀死。
虽然这是一个守护进程,但我们将它作为普通线程而不是守护线程启动。当一个线程被设置为守护线程时,它不会使 JVM 保持活动状态。当所有其他非守护线程停止时,JVM 将退出,守护线程将停止。在我们的例子中,我们执行的守护线程是保持代码运行的唯一线程。在启动之后,主线程就没有什么事情可做了,但是 JVM 应该保持活动状态,直到运算符发出 Unix`kill`命令或在命令行上按`Ctrl + C`将其杀死。
使用 JDK 中新的`Files``Paths`类,获取指定目录中的文件列表并从文件中获取参数非常简单:
......@@ -449,7 +449,7 @@ private void keepProcessesAlive() {
重要的是要理解这个调用不是从`keepProcessesAlive()`方法本身执行的。这不是递归调用。这被安排为一个`CompletableFuture`动作。我们不是在递归调用中实现循环,因为我们会耗尽栈空间。我们要求 JVM 执行者在进程重新启动时再次执行这个方法。
JVM 使用默认的`ForkJoinPool`来调度这些任务,这个池包含守护进程线程。这就是我们必须等待并保持方法运行的原因,因为这是唯一阻止 JVM 退出的非守护进程线程。
JVM 使用默认的`ForkJoinPool`来调度这些任务,这个池包含守护线程。这就是我们必须等待并保持方法运行的原因,因为这是唯一阻止 JVM 退出的非守护线程。
下一种方法是`restartProcesses()`,如下所示:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册