如果我在静态块中启动一个线程。 jvm会在加载类之前等待线程完成吗?
static {
System.out.println("static block");
DataRetrievalThread t = new DataRetrievalThread();
t.run();
}
我之所以这样做是因为 我想从服务器检索数据,并且它需要花费太长时间才能获得它。因此,要保留我想要检索它的数据并将其存储在文件中,以便在客户端请求它时 - 它不需要调用服务器来获取信息。
答案 0 :(得分:4)
如果我在静态块中启动一个线程。 jvm会在加载类之前等待线程完成吗?
嗯。是和否,没有。
首先,您的代码不会分支线程。因此,当它被写入时,将保持类构造,尽管技术上该类在static
部分运行之前被“加载”。那是因为您正在当前主线程中直接执行run()
方法。如果你想分叉线程,那么你应该调用t.start();
。
如果您实际使用t.start()
分叉线程,那么该线程将在后台运行,并且不会阻止类初始化。
你真的应该不做这样的事情。这是一个非常糟糕的模式。如果你解释一下你想要完成什么,我们应该能够真正帮助。
如果您尝试将数据预先加载到程序中,那么您应该尽早在main()
中运行加载部分,而不要将其停放在类中的static
初始值设定项中。但是如果你在主线程中运行它,拿起程序,我不明白为什么这会比按需提出请求更快。
要考虑的一件事是fork(使用t.start()
)后台线程来加载数据,然后有一个保存数据的类。如果线程及时完成,那么它将预先加载数据。当程序需要数据时,它应该调用类来获取它。如果线程尚未完成,则可以执行countDownLatch.await()
。当线程完成下载时,它可以countDownLatch.countDown()
。所以你会得到一些并行性。
类似的东西:
public class DataLoader {
private Stuff data;
private final CountDownLatch latch = new CountDownLatch(1);
// start the thread, called early in main()
public void init() {
// you pass in this so it can call setData
DataRetrievalThread t = new DataRetrievalThread(this);
t.start();
}
// called from the DataRetrievalThread
public void setData(Stuff data) {
this.data = data;
latch.countDown();
}
public Stuff getData() {
if (data == null) {
latch.await();
}
return data;
}
}
答案 1 :(得分:3)
使用run()
执行当前线程中的方法,之后类将完成加载。您需要调用start()
以在新线程中运行该方法。