当用户触发cancel命令时停止线程

时间:2009-06-20 09:21:59

标签: java-me

移动应用程序为用户提供从远程下载电子邮件附件的选项。与远程服务器连接并下载内容是在单独的线程中执行的。使用cancel命令向用户显示一个对话框.Herewith我是提供伪代码。

new Thread(new Runnable()
   public void run(){
     try{
     //open connection to remote server
     //get data input stream
     //create byte array of length attachment size
     //show modeless dialog with the message "Downloading..."
     for(int i=0;i<attachmentSize;i++){
       //set the progress indicator of the modeless dialog based upon for iteration
       //read the byte from input stream and store it in byte array
     }
       //open file connection outputstream and store the downloaded content as a file in mobile file system
       //show dialog with the message "attachment successfully downloaded"
      }
      catch(IOException ioe) { }
      catch(Exception ex) { }
   }
).start();

现在我正在将取消命令添加到带有进度指示器的对话框中。当用户在移动设备中单击“取消”命令时,可以通过调用dispose()方法处理无模式对话框。我怎样才能突然停止通过流媒体获取电子邮件附件的线程? 请帮我解决这个问题。

4 个答案:

答案 0 :(得分:2)

你可以突然停止它 - 但它带来了更多麻烦,值得。

这样做的规范方法是在Runnable中检查一个标志:

public class ClassHoldingRunnable {

    private volatile boolean stopRequested = false;

    public void executeAsync() {

        Runnable r= new Runnable() {

            public void run() {

                while ( !stopRequested ) {
                    // do work
                 }
            }
        }

        new Thread(r).start();
    }

    public void cancel() {
        stopRequested = true;
    }
}

一些注意事项:

  • 至关重要,因为stopRequested标志为volatile或具有其他可见性保证(synchronizedLockAtomic),因为它被多个线程访问;
  • 如果最终用户拥有响应式GUI非常重要,您应该经常检查stopRequested;

答案 1 :(得分:1)

有几种免费方法可以中断从Connection读取的线程。

  • 您可能通过循环调用InputStream.read来读取远程数据,因此您可以重用一个相对较小的byte []对象。您可以在每次迭代之前检查布尔成员变量。你真的不需要围绕那个布尔值进行同步,因为它只能在Thread构造之后改变一次值。

  • 关闭Connection意味着你的线程在下次尝试访问它时会抛出IOException。即使另一个Thread正在从Connection的InputStream中读取,正确的JavaME实现也不会使Connection.close()阻塞。

答案 2 :(得分:0)

我不是这方面的专家,因此我的建议含糊不清,因为我对Java线程的经验非常有限。

你无法阻止正在运行的线程。您可以尽快退出。所以你可以做的就是拥有一个你在二级线程中定期测试的共享标志。当主线程设置它以响应取消单击时,辅助线程返回。

答案 3 :(得分:0)

我在C#中的经验更多,但这可能仍然适用......

我认为找到一些只是“杀死一个线程”的方法不仅仅是删除一个对象并跳过它的析构函数。

你可以告诉线程通过中断自杀。然后,您可以使用线程的中断标志作为指示符,或者,如果您在那里有睡眠/等待,则可以捕获中断的异常并在捕获时正确关闭(在finally块中)。这应该或多或少地提供您正在寻找的东西。