[英]Initializing a thread in a static block?
如果我在静态块中启动一个线程。 jvm 会在加载类之前等待线程完成吗?
static {
System.out.println("static block");
DataRetrievalThread t = new DataRetrievalThread();
t.run();
}
我尝试这样做的原因是因为我想从服务器检索数据,而获取数据的时间太长了。 因此,为了保留数据,我想检索它并将其存储在一个文件中,以便当客户端请求它时 - 它不需要调用服务器来获取信息。
如果我在静态块中启动一个线程。 jvm 会在加载类之前等待线程完成吗?
呃。 是和否和否。
首先,您的代码没有分叉线程。 因此,正如它所写的那样,它会阻止类的构造,尽管从技术上讲,类是在static
部分运行之前“加载”的。 那是因为您直接在当前主线程中执行run()
方法。 如果你想 fork 线程,那么你应该调用t.start();
.
如果你真的用t.start()
fork 线程,那么不,线程将在后台运行并且不会阻止类初始化。
你真的不应该做这样的事情。 这是一个非常糟糕的模式。 如果您解释您要完成的任务,我们应该能够真正提供帮助。
如果您尝试将数据预加载到您的程序中,那么您应该在main()
尽早运行加载部分,而不要将其停放在类中的static
初始化程序中。 但是如果你在主线程中运行它,阻止程序,我不明白为什么这比按需发出请求更快。
要考虑的一件事是派生(使用t.start()
)一个后台线程来加载数据,然后有一个保存数据的类。 如果线程及时完成,那么它将预加载数据。 当程序需要数据时,它应该调用该类来获取它。 如果线程还没有完成,它可以执行countDownLatch.await()
。 当线程完成下载时,它可以执行countDownLatch.countDown()
。 所以你会得到一些并行性。
就像是:
public class DataLoader {
private volatile 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;
}
}
使用run()
您可以在当前线程中执行该方法,然后该类将完成加载。 您需要调用start()
在新线程中运行该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.