繁体   English   中英

在静态块中初始化线程?

[英]Initializing a thread in a static block?

如果我在静态块中启动一个线程。 jvm 会在加载类之前等待线程完成吗?

static {
    System.out.println("static block");
    DataRetrievalThread t = new DataRetrievalThread();
    t.run();
}

我尝试这样做的原因是因为我想从服务器检索数据,而获取数据的时间太长了。 因此,为了保留数据,我想检索它并将其存储在一个文件中,以便当客户端请求它时 - 它不需要调用服务器来获取信息。

如果我在静态块中启动一个线程。 jvm 会在加载类之前等待线程完成吗?

呃。 是和否和否。

  1. 首先,您的代码没有分叉线程。 因此,正如它所写的那样,它阻止类的构造,尽管从技术上讲,类是在static部分运行之前“加载”的。 那是因为您直接在当前主线程中执行run()方法。 如果你想 fork 线程,那么你应该调用t.start(); .

  2. 如果你真的用t.start() fork 线程,那么不,线程将在后台运行并且不会阻止类初始化。

  3. 你真的应该做这样的事情。 这是一个非常糟糕的模式。 如果您解释您要完成的任务,我们应该能够真正提供帮助。

如果您尝试将数据预加载到您的程序中,那么您应该在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM