取消“一会儿”的问题Android 中的循环

发布于 2024-11-19 00:37:45 字数 904 浏览 0 评论 0原文

首先,对于这个不太具有描述性的标题感到抱歉。

我有以下代码,它无法正常工作(或如我想要的那样)。

即使我调用“Cancel()”,但时间仍在继续......

private boolean cancelled;

private synchronized Bitmap renderBitmap(PatchInputStream pis){
              File file = new File(Environment.getExternalStorageDirectory()+url);

              FileOutputStream fos=new FileOutputStream(file);
              byte buf[]=new byte[2000];
              int len;
              while((len=pis.read(buf))>0 && !isCancelled() ){
                  fos.write(buf,0,len);
              }
              fos.close();
              if (isCancelled()){
                cancelled=false;
                return null;
              }

              Bitmap bm = saveBitmapToFile(file);
              return bm;
}

public boolean isCancelled(){
    return cancelled;
}

public void Cancel(){
    cancelled=true;
}

这段代码有什么问题?我错过了什么吗?

First of all, sorry for the not-very-descriptive title.

I've got the following code that it's not working properly (or as I'd wanted).

Even though I call "Cancel()", the while goes on...

private boolean cancelled;

private synchronized Bitmap renderBitmap(PatchInputStream pis){
              File file = new File(Environment.getExternalStorageDirectory()+url);

              FileOutputStream fos=new FileOutputStream(file);
              byte buf[]=new byte[2000];
              int len;
              while((len=pis.read(buf))>0 && !isCancelled() ){
                  fos.write(buf,0,len);
              }
              fos.close();
              if (isCancelled()){
                cancelled=false;
                return null;
              }

              Bitmap bm = saveBitmapToFile(file);
              return bm;
}

public boolean isCancelled(){
    return cancelled;
}

public void Cancel(){
    cancelled=true;
}

What's wrong with this code? Am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

提笔书几行 2024-11-26 00:37:45

至少代码有一个并发错误,可以通过设置 cancelled volatile 来解决。否则,无法保证其他线程看到新值。
(显然情况并非如此。)

另一种可能性是未调用 cancel() 方法。
(显然情况并非如此。)

还有一种可能是在不同的对象实例上调用 cancel() 方法。尝试将 System.out.println(System.identityHashCode(this)) 添加到 cancel() 方法和 while 循环,看看它们是否打印相同的值。

At least the code has a concurrency bug which can be solved by making cancelled volatile. Otherwise the other thread is not guaranteed to see the new value.
(Apparently this was not the case.)

Another possibility is that the cancel() method is not called.
(Apparently this was not the case.)

Still one more possibility is that the cancel() method is being called on a different object instance. Try adding System.out.println(System.identityHashCode(this)) to both the cancel() method and the while loop and see if they print the same value.

沧桑㈠ 2024-11-26 00:37:45

按照 @mibollma 的建议,在已取消的实例变量上使用 volatile 。这将确保没有线程正在使用变量的缓存版本。如果这不起作用,您可以尝试以下建议:

您的 cancel() 方法可能没有被调用,带有 while 循环的线程不允许这样做。使用 Thread.yield() 方法。

使当前正在执行的线程对象暂时暂停并允许其他线程执行。

在你的 while 循环中:

          while((len=pis.read(buf))>0 && !isCancelled() ){
              fos.write(buf,0,len);
              Thread.yield();
          }

Use volatile on the cancelled instance variable as suggested by @mibollma. This will assure that no Thread is using a cached version of the variable. If that does not work, you can try the following suggestion:

Your cancel() method is probably not being invoked, the Thread with the while loop is not permitting it. Use the Thread.yield() method.

Causes the currently executing thread object to temporarily pause and allow other threads to execute.

In your while loop:

          while((len=pis.read(buf))>0 && !isCancelled() ){
              fos.write(buf,0,len);
              Thread.yield();
          }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文