有人告诉我,创建一个新实例总是一条异步消息。但我不明白为什么。
例如:
Foo myFoo = new Foo();
在这里,我将不得不等待构造函数完成并返回我的新对象。但是异步并不意味着我独立地(无需等待)继续进行-就像启动线程一样吗?
有人告诉我,创建一个新实例总是一条异步消息。
抱歉,我不得不说你听错了或者被告知错了。但是首先,我们应该弄清楚一些术语。术语“异步”或“异步”是指调用立即返回给调用者。通过一个简单的实验[1],我们可以很容易地证明这对于构造函数是不正确的。换句话说,构造函数必须返回以便调用者进行任何进度。
启动线程确实是异步的。调用Thread.start()
立即返回,并在稍后的某个时间点线程真正开始运行并执行该run()
方法。
考虑您的班级(仅供参考)如下:
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
添加呼叫只是为了使其可以承受。您可以在没有它的情况下尝试该实验,但是您的程序会将其强调为100%,从而使其中一个CPU不堪重负。
如果在运行时进行了线程转储(例如,通过使用命令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)
这意味着调用者(在本例中为main thread
)将永远不会取得任何进展。并且由于此构造函数永远不会返回,因此不会发生任何进展。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句