我如何检查动态线程是否结束

时间:2013-04-10 19:12:16

标签: java android multithreading

我有imageurl数组,通过DownloadFromUrl函数下载,从myfunction调用,我使用线程,我不知道有多少图像网址,为每个图像下载单独的线程创建,我想要开始一个活动毕竟这些线程的结束。

我怎么能得到所有这些线程,线程睡眠时间更长不能正常工作它不是一个好的程序。我也不能指望静态变量计数结束线程,因为有时图像无法下载或网址损坏,或连接没有超时,

我现在很少迷失,是什么程序才能弄清楚这些所有线程的结束?

public void DownloadFromUrl(String DownloadUrl, String fileName) {

               try {
                       File root = android.os.Environment.getExternalStorageDirectory();               

                       File dir = new File (root.getAbsolutePath() + "/"+Imageurl.facebookpage);
                   if(dir.exists()==false) {
                        dir.mkdirs();
                   }

                   URL url = new URL(DownloadUrl); //you can write here any link
                   File file = new File(dir, fileName);



                   /* Open a connection to that URL. */
                   URLConnection ucon = url.openConnection();

                   /*
                    * Define InputStreams to read from the URLConnection.
                    */
                   InputStream is = ucon.getInputStream();
                   BufferedInputStream bis = new BufferedInputStream(is);

                   /*
                    * Read bytes to the Buffer until there is nothing more to read(-1).
                    */
                   ByteArrayBuffer baf = new ByteArrayBuffer(5000);
                   int current = 0;
                   while ((current = bis.read()) != -1) {
                      baf.append((byte) current);
                   }


                   /* Convert the Bytes read to a String. */
                   FileOutputStream fos = new FileOutputStream(file);
                   fos.write(baf.toByteArray());
                   fos.flush();
                   fos.close();
                   LoginActivity.statsofdownload++;

                   Log.d("DownloadManager","file://"+file.getAbsolutePath());

           } catch (IOException e) {
               Imageurl.pagestat="space";
               Log.d("DownloadManager", "Error: " + e);
           }

        }




myfunction()
{
 for(String string : Imageurl.output) {
                            imagea++;
                        final   int ind =imagea;
                        final String ss=string;
                        new Thread(new Runnable() {
                                public void run() {
                                      DownloadFromUrl(ss,"IMAGE"+ind+".jpeg");
                                      File root = android.os.Environment.getExternalStorageDirectory();         




                                   Imageurl.newyearsvalues.add("file://"+root.getAbsolutePath() + "/"+Imageurl.facebookpage+ "/"+"IMAGE"+ind+".jpeg");

                              }
                                }).start();


                    }

//// now need to call an activity but how I will know that these thread all end
}

3 个答案:

答案 0 :(得分:2)

替代方案1 :将ExecutorServiceshutdown()awaitTermination()一起使用:

ExecutorService taskExecutor = Executors.newFixedThreadPool(noOfParallelThreads);
while(...) {
  taskExecutor.execute(new downloadImage());
}
taskExecutor.shutdown();
try {
  taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
  ...
}

基本上,shutdown()的作用是阻止ExecutorService接受任何更多的线程请求。 awaitTermination()等待ExecutorService完成所有线程的执行。

替代方案2:使用CountDownLatch

CountDownLatch latch = new CountDownLatch(totalNumberOfImageDownloadTasks);
ExecutorService taskExecutor = Executors.newFixedThreadPool(noOfParallelThreads);
while(...) {
  taskExecutor.execute(new downloadImage());
}

try {
  latch.await();
} catch (InterruptedException E) {
   // handle
}

并在你imageDowloader()函数中添加行:

latch.countDown();

每次执行时,这将使锁存器的值增加1。

答案 1 :(得分:1)

您可能希望使用单个ThreadPoolExecutorexecute方法,而不是为每个runnable创建一个新线程,这样您就可以在完成工作后重用线程。

至于确定线程何时完成,使用静态ConcurrentLinkedQueue跟踪成功完成,使用另一个静态ConcurrentLinkedQueue来跟踪可能需要重试的不成功完成。然后在run()方法中包含代码

public void run() {
    try {
        ...
        successfulCompletionQueue.offer(this);
    } catch (Exception ex) {
        unsuccessfulCompletionQueue.offer(this);
    }
}

其中this是任何记录信息与手头的任务相关。

答案 2 :(得分:1)

要识别完成,请使用asynctaskonPostExceute()方法确保下载所有图像,如果您需要在下载时继续下载以使用图像,还可以查看进度。

onPostExecute()方法在ui线程中运行时,现在应该没有任何问题。

但请记住同一asynctask不能多次执行。在这种情况下,您有两个选择:

  1. 在一个asynctastask下载所有图片,并从onPostExecute()
  2. 更新活动
  3. 为每次下载执行单独的asynctask。并使用每个onPostExecute()更新活动。