我正在阅读Brian Goetz 的这篇文章。在不要从构造函数内启动线程部分下,他说“清单 4 中问题的一个特殊情况是从构造函数内启动一个线程,因为通常当一个对象拥有一个线程时,该线程是一个内部类,或者我们将 this 引用传递给它的构造函数(或者类本身扩展了 Thread 类)。如果一个对象要拥有一个线程,最好该对象提供一个 start() 方法,就像 Thread 一样,并启动线程来自 start() 方法而不是来自构造函数。” 他所说的“通常当一个对象拥有一个线程”是什么意思?
3 回答
它可以是其中一个,也可以是两者。线程由对象(java.lang.Thread
类的实例)表示,该对象与其他对象的关系完全取决于您。
如果线程中运行的代码创建了一些仅由线程使用的对象,您可以将这些对象视为线程拥有的。如果您有其他对象负责创建、启动和控制线程,您可以认为该对象拥有该线程。但是这些东西都不是 Java 要求或强制执行的。这是您在设计软件时的选择。
Goetz 的意图非常简单,并不特定于Thread
. 它只是意味着一个对象Thread
通过组合关系拥有该实例——它拥有对它的私有引用,并且不允许任何外部对象访问它。
您还可以注意到,这种所有权并不是真正可执行的,因为在该线程上执行的任何代码也可以通过该方法访问Thread
实例。currentThread
我不认为 Goetz 意味着过于从字面上理解拥有线程的对象。他只是意味着线程是在其他对象的构造函数中启动的,因此它可能在它有机会完成构造之前访问该对象的状态。没有正式的、有意义的所有权关系,这都是上下文相关的。例如,您可能会说拥有对线程的引用的人是所有者,因为他们可以取消它,但是引用可以传递,首先创建线程的对象没有什么特别之处。
如果您阅读 Goetz 的《Java Concurrency in Practice 》一书,它涵盖了线程限制等设计技术,其中线程交互的事物范围受到限制。您还可以创建对象,以便只有一个线程可以看到它们,例如在使用 ThreadLocal 时。因此,您可以设计抽象来创建所有权关系,但这取决于您。