【问题标题】:Synchronized methods within AsyncTasksAsyncTasks 中的同步方法
【发布时间】:2018-06-14 19:37:44
【问题描述】:

我的应用程序正在从传感器收集数据,我让用户手动保存标签。每当用户触摸按钮以保存标签时,我都会运行 AsyncTask 并在 doInBackground 方法中调用同步方法,其唯一目的是将信息保存在文件中。该方法是帮助程序库的一部分,因此我将其作为静态方法访问,因此它是同步的静态方法。我需要按照输入的顺序保存标签。但是,我注意到有时标签以不同的顺序保存,这告诉我同步方法可能无法按预期工作

  1. AsyncTasks 中的同步方法是否有任何限制?
  2. 有没有更好的方法来做到这一点?我的意思是,继续将数据保存在后台线程中,但确保如果我们有多个,我按照它们到达的顺序执行它们?

代码看起来有点像这样:

public class FileUtil {
    public static synchronized void saveActivityDataToFile() throws IOException{
       //Saving file code
    }
}

//This asynctask is called everytime the user touches the button
private class SaveDataInBackground extends AsyncTask<String, Integer, Void> {

    public SaveDataInBackground(){
    }

    protected Void doInBackground(String... lists) {
        try {
            //I expect this to run on its own thread but synchronously if this asynctask is called multiple times withing a short interval of time
            FileUtil.saveActivityDataToFile();
        }catch (IOException e){
            Log.e(TAG,"Error while saving activity: " + e.getMessage());  
        }
        return null;
    }

    protected void onPostExecute(Void v) {
    }
}

【问题讨论】:

  • 没有限制,但是你可能会导致饥饿或死锁。您应该始终确保同步方法快速完成,尤其是在 AsyncTask 中。
  • @user1055395 这就是我调用异步任务的方式。 SaveDataInBackground backgroundSave = new SaveDataInBackground(this); backgroundSave.execute(timestamp, label);
  • 那么,@GabeSechan 你认为以这种方式保存文件不是一个好主意吗?对于这种特殊情况,我只是保存一个不应该长于 50 个字符的标签。但是,我计划对更大的文件使用相同的方法。
  • 不,在 AsyncTask 上调用同步函数完全没问题,只要该对象上的同步函数不会在不合理的时间内持有锁。保存文件是一个完全合理的保存时间。我会担心任何可能需要几秒钟以上的事情,但不会担心任何需要毫秒的事情。

标签: android android-asynctask synchronized


【解决方案1】:
  1. AsyncTasks 中的同步方法没有任何限制

顺便说一句,同步与顺序无关,它与阻塞部分代码有关,仅用于一个线程。所以可能会有这样的情况:

任务 1 开始

任务 2 开始

任务 2 编写并完成

任务 1 编写并完成

  1. 您可以使用Thread 代替AsyncTask。然后只使用一个线程使用ThreadPoolExecutor 或使用thread.join()

但最好使用RxJava2Kotlin Coroutines 处理此类事情

【讨论】:

  • 我知道同步它关于阻塞,但是任何其他尝试访问的线程会发生什么?比方说,在任务 1 开始并被阻止之后,任务 2 和任务 3 以该顺序启动。怎么了?任务 2 和 3 是简单地完成还是等到任务 1 发布,然后在发布时,任务 2 在任务 3 之前执行?
  • @Roger,任务 2 和 3 等到任务 1 释放部分代码,并且应该以相同的顺序继续执行
  • @Roger 如果您使用 execute() 启动 AsyncTask,那么所有请求都会在队列中运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 2011-11-08
相关资源
最近更新 更多