【问题标题】:Will a method be blocking if the return value depends on the result of a blocking operation?如果返回值取决于阻塞操作的结果,方法是否会阻塞?
【发布时间】:2012-08-29 09:06:21
【问题描述】:

我在一个继承自Thread类的类中写了如下方法:

protected File createFile(String fileName){
        try {
            File file = new File(fileName);
            if(!file.exists())
                file.createNewFile();
            else{
                file.delete();
                file.createNewFile();
            }
            file.mkdirs();
            return file;
        }catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

一旦线程已经启动,它将从活动中调用。如果我从我的活动中这样做:

File logFile = mThread.createFile("/Logs/test.txt");
if(logFile!=null)
//do something
else
//do something else

在创建文件之前它会阻塞吗?

【问题讨论】:

  • 它将在调用线程上运行 - 如果您从 UI 线程调用它,它将阻塞您的活动,如果您从您创建的线程调用它,它将在该线程上运行。跨度>
  • 您是否在关注 Thread 文档? (developer.android.com/guide/components/…) 如果您刚刚启动,请改用 AsyncTask (developer.android.com/reference/android/os/AsyncTask.html) 它更清楚什么在哪里运行..
  • 您在发布问题之前是否亲自检查过?
  • 是的,它确实创建了文件,但我想知道主要活动是否暂时被阻止。我以前使用过 AsyncThread,但我正在尝试编写一个无限期运行的单个线程,并且仅在从活动中调用其方法时才执行 IO 操作。

标签: java android multithreading file blocking


【解决方案1】:

是的,它会阻塞。

重要的不是调用方法的类,而是调用它的线程的run() 方法。很有可能

File logFile = mThread.createFile("/Logs/test.txt");
if(logFile!=null)
//do something
else
//do something else

从你的活动run方法调用(由android处理),直接从另一个线程类调用方法不会神奇地让这个线程运行这个方法。

为确保您不会使用此createFile 方法阻止您的活动,您应该使用消息传递机制,以便在您的非活动线程的run() 方法中调用createFile。

请参阅this post 中的示例,了解如何在线程之间传递消息。总而言之,您的活动线程将从您的其他线程设置一个变量。该线程定期检查此变量并根据它执行操作。这是主要思想,但关于线程安全和在这些情况下出现的其他问题,有很多内容需要阅读 on the web。

【讨论】:

    【解决方案2】:

    您的Activity 是一组由Android 在UI 线程上调用的回调方法。这些回调在Activity 的生命周期内执行(如文档中详细描述的那样)。在执行一个回调时,不会执行其他与 UI 相关的回调。

    如果任何一个回调需要很长时间,那么 UI 就会停止响应(您经常会看到这被称为“UI 被阻止”)。

    回答实际问题:是的,UI 线程将在等待您的回调完成时停止处理其他事件,包括对 createFile 方法的调用。

    我在这里假设(因为从问题中不清楚)对createFile 的调用是在Activity 生命周期回调方法之一(如onCreate)或与@ 相关的UI 事件回调987654327@(就像在Activity 上附加到Button 的OnClickListener)。


    如果您不想在创建文件时阻止 UI 线程,那么您需要从不同的“后台”线程执行调用 createFile。

    注意,如果您需要从“后台”线程对 UI 进行更新,您必须确保将对 Android UI API 的调用安排在 UI 线程上进行。

    这可以使用 Thread 和 Handler 对象来完成,但使用 AsyncTask 通常更方便,因为它提供了一个方便的方法框架,可以在后台任务和 UI 的正确线程上调用更新。

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2019-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多