2013-10-05 48 views
0

我正在创建一个Java应用程序。在启动时,我的应用程序将下载所有必需的文件。我的应用程序将解析XML文件并从XML文件的URL中下载文件。我希望我的应用程序下载文件“一步一步”,所以我使用FutureTask我的问题是,FutureTask不适用于我的应用程序。Java - FutureTask不工作?

这是我的代码的一部分。

Startup.class

public void startDownloading() 
{ 

    Thread t = new Thread(new Runnable() 
    { 
     public void run() 
     { 
      downloader.startDownload(); 
     } 
    }); 
    t.run(); 
    } 
} 

Downloader.class

private LibrariesDownloader ld; 
private RDownloader rd; 

public Downloader() 
{ 
    this.ld = new LibrariesDownloader(launcher); 
    this.rd = new RDownloader(launcher); 
} 

public void startDownload() 
{ 
    ExecutorService executor = Executors.newFixedThreadPool(2); 
    FutureTask<Void> libDownloader = new FutureTask<Void>(ld); 
    FutureTask<Void> resDownloader = new FutureTask<Void>(rd); 
    executor.execute(libDownloader); 
    if(libDownloader.isDone()) 
    { 
     executor.execute(resDownloader); 
    } 
} 

LibrariesDownloader.class(& RDownloader.class(代码几乎相同,唯一的URL是不同的))

public class LibrariesDownloader implements Callable<Void> 
{ 
    private Proxy proxy = Proxy.NO_PROXY; 

    @Override 
    public Void call() throws Exception 
    { 
     try 
     { 
      URL resourceUrl = new URL("http://www.exmaple.com/libraries.xml"); 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 

      Document doc = db.parse(resourceUrl.openConnection(proxy).getInputStream()); 

      NodeList nodeLst = doc.getElementsByTagName("Content"); 
      for (int i = 0; i < nodeLst.getLength(); i++) 
      { 
       Node node = nodeLst.item(i); 

       if (node.getNodeType() == 1) 
       { 
        Element element = (Element)node; 
        String key = element.getElementsByTagName("Key").item(0).getChildNodes().item(0).getNodeValue(); 
        final File path = new File("C://test/", key); 
        final String url = "http://www.exmaple.com/dl/" + key; 
        final String fileName = key; 
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() 
        { 
         @Override 
         protected Void doInBackground() throws Exception 
         { 
          try 
          { 
           URL fileURL = new URL(url); 
           org.apache.commons.io.FileUtils.copyURLToFile(fileURL, path); 
          } 
          catch(Exception e) 
          { 

           URL redownloadURL = new URL("http://www.example.com/dl/" + fileName); 
           File p = new File("C://test/", fileName); 
           org.apache.commons.io.FileUtils.copyURLToFile(redownloadURL, p); 
          } 
          return null; 
         } 

         @Override 
         public void done() 
         { 
          System.out.println(fileName + " had downloaded successfully"); 
         } 
        }; 
        worker.execute(); 


        } 
       } 
      } 
      catch(Exception e) 
      { 
       launcher.println("An error was found when trying to download libraries file " + e); 
      } 
      return null; 
     } 

} 

我的XML文件中有大量的<Key></Key>。我的应用程序可以执行LibrariesDownloader并下载所有库文件。所有库文件下载后,我的应用程序就停在那里。它不会执行RDownloader

是我的应用程序中的任何代码错误?感谢您的帮助。

+0

定义 “不工作”。此外,您应该阅读Thread.run(),Thread.start()和FutureTask.isDone()的javadoc。目前还不清楚,只是从代码中,你正在尝试做什么。 –

+0

我想在LibrariesDownloader.class下载文件后,RDownloader会启动并下载“R”文件 – Jeremy

+1

所以你需要顺序执行而不是并行执行。为什么使用线程呢?正如我所说的,阅读isDone()的javadoc。这不是一种阻止方法。 get()是一种阻塞方法。 –

回答

1

就启动了一个新线程

t.run();

它应该是t.start()。线程调度程序调用run()

你可能要忙/等待环路或LibrariesDownloader

if(libDownloader.isDone()) 
    { 
     executor.execute(resDownloader); 
    } 

超时应该

Future<?> future = executor.submit(libDownloader); 

while (!future.isDone()) { 
    //bad spin wait 
} 

executor.execute(resDownloader); 

更妙的是,做与Executors.newSingleThreadExecutor()单一的ThreadPoolExecutor或更强大的Executors.newFixedThreadPool(1)并提交两其中。第二项任务将排队。

的代码片段看起来像

ExecutorService executor = Executors.newFixedThreadPool(1); 
executor.execute(libDownloader); 
executor.execute(resDownloader); 
+0

nonono,我想''LibrariesDownloader'完成下载后,'RDownloader'将启动并再次下载另一个文件列表 – Jeremy

+0

@ user2718549这就是发生的事情。除非'LibrariesDownloader'完成,'RDownloader'不会启动。你有没有尝试过这些代码? – bsd

+0

我尝试了所有的代码,它们都不起作用,它会同时启动'LibrariesDownloader'和'RDownloader' ... – Jeremy