有人告诉我,创建一个新实例总是一个异步消息;但我不明白为什么。
例如:
Foo myFoo = new Foo();
在这里,我必须等到构造函数完成并返回我的新对象。但是异步不是意味着我独立继续(无需等待)- 就像启动一个线程一样?
最佳答案
I was told, that creating a new instance is always an async message;
对不起,我不得不说,要么你听错了,要么你被告知了一些错误的事情。但首先,我们应该弄清楚一些术语。术语“异步”或“异步”表示调用立即 返回调用方。通过一个简单的实验 [1],我们可以很容易地证明构造函数不是这样的。换句话说,构造函数必须返回调用方才能取得任何进展。
启动线程确实是异步的。对 Thread.start()
的调用立即返回,并在稍后的某个时间点线程实际开始运行并执行 run()
方法。
1 实验
考虑你的类(class)(仅供引用)如下:
Foo.java
class Foo {
Foo() throws InterruptedException {
while (true) {
System.out.println("not returning yet ...");
Thread.sleep(2000);
}
}
public static void main(String[] args) throws InterruptedException {
Foo foo = new Foo();
}
}
如果您编译并运行此类(我在 Mac 上使用 Java 8,但这不是必需的)。正如预期的那样,这个类永远运行,每 2 秒产生一次输出:
not returning yet ...
not returning yet ...
not returning yet ...
not returning yet ...
请注意,添加 sleep
调用只是为了让它可以忍受。您可以不尝试此实验,但随后您的程序会将其中一个 CPU 的压力提高到 100%。
如果在它运行时进行了线程转储(例如,通过使用命令 jstack
),您会看到如下所示的内容(为简洁起见进行了缩减):
"main" #1 prio=5 os_prio=31 tid=0x00007f9522803000 nid=0xf07
waiting on condition [0x000000010408f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
无论线程的状态如何(RUNNABLE、BLOCKED、WAITING、TIMED_WAITING
),您总是会看到(获取各种线程转储以了解这意味着什么)您总是会看到这两行:
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
这意味着调用者(在本例中为主线程
)永远不会取得任何进展。由于此构造函数永远不会返回,因此不会发生任何进展。
关于java - 为什么 'create'是异步的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38223660/