简体   繁体   English

在静态块中初始化线程?

[英]Initializing a thread in a static block?

If I start a thread in a static block.如果我在静态块中启动一个线程。 Will the jvm wait for the thread to finish before it loads the class? jvm 会在加载类之前等待线程完成吗?

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

The reason I'm trying this is because I want to retrieve data from a server and it's taking way too long to get it.我尝试这样做的原因是因为我想从服务器检索数据,而获取数据的时间太长了。 So to persist the data I want to retrieve it and store it in a file so that when the client asks for it - it does not need to make the call to the server to get the information.因此,为了保留数据,我想检索它并将其存储在一个文件中,以便当客户端请求它时 - 它不需要调用服务器来获取信息。

If I start a thread in a static block.如果我在静态块中启动一个线程。 Will the jvm wait for the thread to finish before it loads the class? jvm 会在加载类之前等待线程完成吗?

Uh.呃。 Yes and no and NO.是和否和否。

  1. First off, your code is not forking a thread.首先,您的代码没有分叉线程。 So as it is written it will hold up the class construction although technically the class is "loaded" before the static section runs.因此,正如它所写的那样,它阻止类的构造,尽管从技术上讲,类是在static部分运行之前“加载”的。 That's because you are executing the run() method directly in the current main thread.那是因为您直接在当前主线程中执行run()方法。 If you want to fork the thread then you should call t.start();如果你想 fork 线程,那么你应该调用t.start(); . .

  2. If you actually fork the thread with t.start() then no, the thread will run in the background and will not hold up the class initialization.如果你真的用t.start() fork 线程,那么不,线程将在后台运行并且不会阻止类初始化。

  3. You really should not be doing something like this.你真的应该做这样的事情。 It's a tremendously bad pattern.这是一个非常糟糕的模式。 If you explain what you are trying to accomplish, we should be able to really help.如果您解释您要完成的任务,我们应该能够真正提供帮助。

If you are trying to pre-load data into your program then you should just run the load part early on in main() and don't park it in a static initializer in a class.如果您尝试将数据预加载到您的程序中,那么您应该在main()尽早运行加载部分,而不要将其停放在类中的static初始化程序中。 But if you are running it in the main thread, holding up the program, I don't see why this is any faster then making the request on demand.但是如果你在主线程中运行它,阻止程序,我不明白为什么这比按需发出请求更快。

One thing to consider is to fork (with t.start() ) a background thread to load the data and then have a class which holds the data.要考虑的一件事是派生(使用t.start() )一个后台线程来加载数据,然后有一个保存数据的类。 If the thread finishes in time then it will have pre-loaded the data.如果线程及时完成,那么它将预加载数据。 When the program needs the data, it should call the class to get it.当程序需要数据时,它应该调用该类来获取它。 If the thread hasn't finished it could do a countDownLatch.await() .如果线程还没有完成,它可以执行countDownLatch.await() When the thread finishes the download it could do countDownLatch.countDown() .当线程完成下载时,它可以执行countDownLatch.countDown() So you will get some parallelism.所以你会得到一些并行性。

Something like:就像是:

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;
    }
}

With run() you execute the method in the current thread, so after that the class will finish loading.使用run()您可以在当前线程中执行该方法,然后该类将完成加载。 You need to call start() to run the method in a new thread.您需要调用start()在新线程中运行该方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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