android - 多线程应用程序中的同步阻塞

标签 android service input concurrency synchronized

下面您会看到一些运行良好的代码 - 但只能运行一次。它应该阻塞直到 runOnUIThread 完成。当它第一次运行时它被调用时确实如此。但是当第二次调用时,它会一直运行到最后,然后 runOnUIThread 开始运行。可能是,该方法第一次运行后,调用它的线程仍然拥有锁,当它第二次调用该方法时,它就跑通了。这是正确的吗?我能做些什么来解决这个问题?或者是时序问题,第二次调用者先获得锁?

static Integer syn = 0;
@Override 
public String getTanFromUser(long accid, String prompt) {
    // make parameters final
    final long accid_int = accid;
    final String prompt_int = prompt;
    Runnable tanDialog = new Runnable() {
        public void run() {
            synchronized(syn) {
                tanInputData = getTANWithExecutionStop(TransferFormActivity.this);
                syn.notify() ;
            }
        }
    };
    synchronized(syn) {
        runOnUiThread(tanDialog);
        try {syn.wait();} 
        catch (InterruptedException e) {} 
    }
    return tanInputData;
}

后台:调用此方法的线程是绑定(bind)服务内的异步任务,该服务正在后台与银行进行交易。银行不定期地发送用户验证请求(验证码、控制问题、PIN 请求等),并且服务必须通过对前台 Activity 的弱引用回调显示一些对话框。由于服务正在执行多个嵌套的 while 循环,因此同步显示对话框比停止重新启动服务更容易(保存/恢复状态数据太复杂)。

最佳答案

您可以尝试一下,如果在 FutureTask 中使用 Callable 而不是 Runnable 效果更好。据我所知,这种组合意味着提供线程的返回值。

public String getTanFromUser(long accid, String prompt) {
    // make parameters final
    final long accid_int = accid;
    final String prompt_int = prompt;
    Callable<String> tanDialog = new Callable<String>() {
        public String call() throws Exception {
            return getTANWithExecutionStop(TransferFormActivity.this);
        }
    };
    FutureTask<String> task = new FutureTask<String>(tanDialog);
    runOnUiThread(task);
    String result = null;
    try {
        result = task.get();
    }
    catch (InterruptedException e) { /* whatever */ }
    catch (ExecutionException e) { /* whatever */ }
    return result;
}

一个Callable类似于 Runnable 但有返回值。

一个FutureTask进行同步并等待结果。与您的 wait()/notify() 类似。 FutureTask 还实现了 Runnable,因此它可用于 runOnUiThread

关于android - 多线程应用程序中的同步阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13182397/

相关文章:

C 程序在轨道数组中搜索轨道

java - GSON fromJSON 反序列化,有条件排除特定对象实例

android - 如何查看我的应用程序是否安装在 SD 卡上

spring - 如何使用 Spring 注解实现远程处理?

model-view-controller - 在 MVC 架构中实现服务层

android - SDK 中的 Android 服务问题 >= 26

css - 为单个输入 ID 定义 CSS 样式,而不是 input[type=checkbox]

android - 使用android在sqlite数据库中插入和检索图像数据的问题

android - 为什么android studio要组装我们的动态功能模块测试apk?

linux - 停止缓冲区溢出 - NASM 输入