2013-04-19 67 views
2

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

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

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

回答

4

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

呃。是,否,不。

  1. 首先,您的代码不是分叉线程。因此,它被写入举行类建设,虽然技术上该类是在“static”部分运行之前“加载”。这是因为您正在当前主线程中直接执行run()方法。如果你想分叉线程,那么你应该拨打t.start();

  2. 如果你实际上将线程与t.start()分开,那么no,线程将在后台运行并且不会阻塞类的初始化。

  3. 你真的应该不是做这样的事情。这是一个非常糟糕的模式。如果你解释你正在努力完成什么,我们应该能够真的帮助

如果你正在尝试将数据加载预到你的程序,那么你只应该早在main()运行负荷部分,在一个类中的static初始化不停放。但是,如果你在主线程中运行它,举起程序,我不明白为什么这么做会比按需提出请求更快。

需要考虑的一件事是分叉(用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; 
    } 
} 
+0

添加了一些代码@ 12rad。 – Gray

3

With run()您在当前线程中执行该方法,因此在该类之后该类将完成加载。您需要致电start()以在新线程中运行该方法。